Какая разница между "git reset" и "git checkout"?

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

ADDED

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

http://a.imageshack.us/img192/5440/screenshot20100903at416.png

ADDED 2

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

http://a.imageshack.us/img651/1559/86421927.pnghttp://a.imageshack.us/img801/1986/resetr.png

ДОБАВЛЕНО 3

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

введите описание изображения здесь

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

введите описание изображения здесь

316
задан prosseek 03 сент. '10 в 23:21
источник поделиться

5 ответов

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

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

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

Все эти три изменения рабочего дерева (svn checkout, update, switch) имеют только одну команду в git: git checkout.
Но поскольку git имеет также понятие индекса ( "область постановки" между репо и рабочим деревом), вы также имеете git reset.


Thinkeye упоминает в комментариях статью Reset Demystified ".

Например, если у нас есть две ветки: "master" и "develop", указывающие на разные коммиты, и в настоящее время мы находимся на "develop" (поэтому HEAD указывает на нее), и мы запускаем git reset master, 'develop' теперь будет указывать на то же сообщение, что и 'master'.

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

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

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

134
ответ дан VonC 03 сент. '10 в 23:29
источник поделиться

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

Сбрасывает индекс в соответствии с HEAD, дерево обработки остается в покое:

git reset

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

git checkout

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

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

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

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

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

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

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

53
ответ дан Charles Bailey 03 сент. '10 в 23:43
источник поделиться

Один простой случай использования при возврате изменений:
1. Используйте reset, если вы хотите отменить установку измененного файла.
2. Используйте checkout, если вы хотите отменить изменения в неустановленном файле/s.

8
ответ дан John Doe 28 янв. '16 в 5:54
источник поделиться

Atlassian дают нам отличное объяснение по поводу git reset, git checkout, и поэтому git возвращает. В этой статье объясняются различные применения этих команд на разных уровнях - файл, поставленный снимок и фиксация.

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

5
ответ дан Rochadsouza 21 марта '15 в 18:55
источник поделиться

Две команды (reset и checkout) совершенно разные.

checkout X НЕ reset --hard X

Если X является именем ветки, checkout X изменит текущую ветвь а reset --hard X - нет.

3
ответ дан wiki1000 11 сент. '15 в 19:01
источник поделиться

Другие вопросы по меткам