Есть ли разница между" git reset --hard hash "и"git checkout hash"?

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

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

может быть, есть разница в том, как вы будете видеть историю?

3 ответов


этот ответ в основном цитируется из моего ответа на предыдущий вопрос:git reset на простом английском языке.

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

предположим, что ваша история выглядит так, с главной веткой в настоящее время проверено:

- A - B - C (HEAD, master)

а ты беги git reset --hard B. Вы получите это:

- A - B (HEAD, master)      # - C is still here, but there's no
                            # branch pointing to it anymore

вы действительно получите этот эффект, если используете --mixed или --soft too-единственная разница заключается в том, что происходит с вашим деревом работы и индексом. В --hard case, дерево работы и индекс совпадают B.

теперь, предположим, вы побежите . Вы получите это:

- A - B (HEAD) - C (master)

вы оказались в отдельной главе государства. HEAD, дерево работы, индекс все Матч B, то же, что и с жестким сбросом, но главная ветвь осталась позади на C. Если вы сделаете новый commit D в этот момент Вы получите это, что, вероятно, не то, что вы хотите:

- A - B - C (master)
       \
        D (HEAD)

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


Если документация, предоставленная с Git, не поможет вам, взгляните на Визуальная Ссылка Git Марк Lodato.

в частности, если вы сравниваете git checkout <non-branch> с git reset --hard <non-branch> (hotlinked):

мастер проверки git~3 http://marklodato.github.com/visual-git-guide/checkout-detached.svg.png

сброс git --жесткий мастер~3 http://marklodato.github.com/visual-git-guide/reset-commit.svg.png

Примечание. что в случае git reset --hard master~3 вы оставляете часть DAG ревизий - на некоторые из коммитов не ссылается ни одна ветвь. Они защищены в течение (по умолчанию) 30 дней reflog; они в конечном счете будут обрезаны (удалены).


git-reset hash устанавливает ссылку на ветку для данного хэша и дополнительно проверяет ее с помощью--hard.

git-checkout hash устанавливает рабочее дерево в заданный хэш; и если хэш не является именем ветви, вы получите отделенную голову.

в конечном счете, git имеет дело с 3 вещами:

                   working tree (your code)
-------------------------------------------------------------------------
                     index/staging-area
-------------------------------------------------------------------------
      repository (bunch of commits, trees, branch names, etc)

git-checkout по умолчанию просто обновляет индекс и рабочее дерево, и при необходимости можно обновить что-то в репозитории (с -b вариант)

git-reset по умолчанию просто обновляет репозиторий и индекс, а также, возможно, рабочее дерево (с помощью )

вы можете думать о репозитории так:

 HEAD -> master

 refs:
    master -> sha_of_commit_X
    dev -> sha_of_commit_Y

 objects: (addressed by sha1)

    sha_of_commit_X, sha_of_commit_Y, sha_of_commit_Z, sha_of_commit_A ....

git-reset манипулирует тем, на что указывают ссылки ветви.

предположим, что ваша история выглядит так:

           T--S--R--Q [master][dev]
          / 
   A--B--C--D--E--F--G [topic1]
                   \
                    Z--Y--X--W [topic2][topic3]

имейте в виду, что ветви-это просто имена, которые автоматически продвигаются при фиксации.

Так вы имеют следующие ветви:

 master -> Q
 dev -> Q
 topic1 -> G
 topic2 -> W
 topic3 -> W

и ваша текущая ветвь -topic2, то есть голова указывает на topic2.

HEAD -> topic2

затем, git reset X сброс именем topic2 чтобы указать на X; то есть, если вы сделаете фиксацию P на ветке topic2, все будет выглядеть так:

           T--S--R--Q [master][dev]
          / 
   A--B--C--D--E--F--G [topic1]
                   \
                    Z--Y--X--W [topic3]
                           \
                            P [topic2]