В чем разница между "git reset" и "git checkout"?


Я всегда думал о git reset и git checkout как то же самое, в том смысле, что оба возвращают проект к определенной фиксации. Однако я чувствую, что они не могут быть точно такими же, поскольку это было бы излишним. Какова реальная разница между ними? Я немного смущен, так как svn имеет только svn co чтобы отменить фиксацию.

добавил

The следующей схеме объясняет разницу, хотя и в возможно упрощенном или неправильном манера. А ты как думаешь? Это неправильно или чрезмерно упрощено?

добавлено 2

Вонк и Чарльз объяснили разницу между git reset и git checkout очень хорошо. Мое текущее понимание заключается в том, что git reset возвращает все изменения обратно к определенной фиксации, тогда как git checkout более или менее готовится к ветке. Я нашел следующие две диаграммы весьма полезными для достижения этого понимания:

добавил 3

от http://think-like-a-git.net/sections/rebase-from-the-ground-up/using-git-cherry-pick-to-simulate-git-rebase.html, проверка и сброс могут эмулировать перебазирование.

git checkout bar 
git reset --hard newbar 
git branch -d newbar 

6 360

6 ответов:

  • git reset это конкретно про обновление индекса, двигая головой.
  • git checkout о Обновление рабочего дерева (к индексу или указанному дереву). Он обновит голову только в том случае, если вы проверите ветку (если нет, вы получите отрезанная голова).

для сравнения, поскольку svn не имеет индекса, только рабочее дерево,svn checkout будет скопируйте данную ревизию в отдельный каталог.
Более близкий эквивалент для git checkout would:

  • svn update (если вы находитесь в той же ветке, что и URL-адрес SVN)
  • svn switch (если вы проверяете, например, ту же ветку, но из другого URL РЕПО SVN)

все эти три модификации рабочего дерева (svn checkout,update,switch) есть только одна команда в git:git checkout.
Но так git также имеет понятие индекса (эта "промежуточная область" между РЕПО и рабочим деревом), у вас также есть git reset.


Thinkeye упоминает в комментариях в статье "Сброс Демистифицированный ".

например, если у нас есть две ветви,'master' и 'develop' указывая на разные коммиты, и мы в настоящее время на 'develop '(так голова указывает на него) и мы бежим git reset master,'' теперь будет указывать на ту же фиксацию, что'master' делает.

С другой стороны, если мы выполним git checkout master,'develop не двинется, будет. HEAD теперь будет указывать на 'master'.

Итак, в обоих случаях мы переезжаем HEAD на момент совершения A, но и как мы это делаем. reset будет двигаться филиала HEAD указывает на, проверка движется HEAD сам указать на другой отделение.

http://git-scm.com/images/reset/reset-checkout.png

в самом простом виде,reset сброс индекса, не касаясь рабочего дерева, в то время как checkout изменяет рабочее дерево, не касаясь индекса.

сбрасывает индекс, чтобы соответствовать HEAD, рабочее дерево осталось в покое:

git reset

концептуально, это проверяет индекс в рабочем дереве. Чтобы заставить его на самом деле делать все, что вам придется использовать -f чтобы заставить его заменить любые локальные изменения. Это функция безопасности, чтобы убедиться, что "нет аргумент " форма не разрушительна:

git checkout

как только вы начинаете добавлять параметры, это правда, что есть некоторое перекрытие.

checkout обычно используется с веткой, тегом или фиксацией. В этом случае он будет сброшен HEAD и индекс для данной фиксации, а также выполнение проверки индекса в рабочем дереве.

также, если вы поставляете --hard до reset вы можете задать reset для перезаписи рабочего дерева, а также сброса индекс.

если у вас в настоящее время есть ветка, проверенная, есть решающее различие между reset и checkout когда вы предоставляете альтернативную ветку или фиксацию. reset изменит текущую ветвь, чтобы указать на выбранную фиксацию, тогда как checkout оставит текущую ветвь в покое, но вместо этого проверит предоставленную ветвь или зафиксирует.

другие формы reset и commit включите поставляя пути.

если вы предоставляете пути к reset вы не могу поставить --hard и reset изменит только индексную версию предоставленных путей к версии в предоставленной фиксации (или HEAD если вы не укажете фиксации).

если вы предоставляете пути к checkout, как reset он обновит индексную версию предоставленных путей в соответствии с предоставленной фиксацией (или HEAD) но он всегда будет проверять версию индекса предоставленных путей в рабочем дереве.

один простой случай использования при возврате изменения:
1. Используйте сброс, Если вы хотите отменить промежуточное размещение измененного файла.
2. Используйте checkout, если вы хотите отменить изменения в unstaged file/s.

Atlassian дайте нам отличное объяснение о git reset,git checkout и так, git revert. В этой статье объясняется различное использование этих команд на разных уровнях - file, staged snapshot и commit.

https://www.atlassian.com/git/tutorials/resetting-checking-out-and-reverting

ключевое различие в двух словах заключается в том, что resetперемещает текущую ветку, а checkout не делает (он двигает головой).

как объясняет книга Pro Git в разделе Сброс Демистифицированный,

первым делом reset будет переместить то, что голова указывает на. Это не то же самое, что меняется сама голова (что такое checkout нет); reset перемещает филиала эта голова указывает на него. Это означает, что если голова установлена к master ветку (т. е. вы в настоящее время на master ветку), работает git reset 9e5e6a4 начнем с изготовления master пункт 9e5e6a4. [курсив добавлен]

см. также ответ VonC для очень полезный текст и схемы выдержка из той же статьи, который я не буду дублировать здесь.

конечно, есть гораздо больше деталей о том, какие эффекты checkout и reset на индекс и рабочее дерево, в зависимости от того, какие параметры используются. Между этими двумя командами может быть много сходств и различий. Но, как я вижу, самое важное различие заключается в том, перемещают ли они кончик текущей ветви.

две команды (сброс и проверка) совершенно разные.

checkout X ЭТО НЕ reset --hard X

если X-это имя ветви, checkout X изменить текущую ветку в то время как reset --hard X не будет.