“ git reset --hard hash”和“ git checkout hash”之间有区别吗?

尽管--hardcheckout大多数情况下都有不同的用法,但我看不出两者之间有什么区别。

可能没有人会不厌其烦地添加--hard选项来执行基本checkout可以执行的操作。

也许您会看到历史的方式有所不同?

e-satis asked 2020-07-31T09:38:27Z
3个解决方案
55 votes

这个答案大部分来自我对上一个问题的回答:git reset用普通英语。

两者有很大的不同。 它们导致索引和工作树的状态相同,但结果历史记录和当前分支不同。

假设您的历史记录如下所示,当前已检出master分支:

- A - B - C (HEAD, master)

并且运行HEAD。您将获得以下信息:

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

如果也使用HEADB,则实际上会获得这种效果-唯一的区别是工作树和索引会发生什么。 在C案例中,工作树和索引匹配D

现在,假设您改为运行HEAD。 你会得到这个:

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

您最终处于分离的HEAD状态。 HEAD,工作树,索引全部匹配B,与硬重置相同,但是master分支留在了C。如果此时进行新的提交D,您会得到的,这可能不是您所需要的 想:

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

因此,您可以使用checkout来签出该提交。 您可以摆弄它,做自己喜欢的事,但是您已经把分支留在了后面。 如果您也希望移动分支,请使用reset。

Cascabel answered 2020-07-31T09:51:40Z
14 votes

如果Git随附的文档对您没有帮助,请参阅Mark Lodato撰写的《 Visual Git参考》。

特别是如果您要比较git reset --hard master~3git reset --hard <non-branch>(热链接):

git checkout master~3
(来源:github.com)

git reset --hard master~3

请注意,对于git reset --hard master~3,您会留下DAG修订的一部分-任何分支都不会引用某些提交。 那些(默认情况下)被reflog保护30天; 他们最终将被修剪(删除)。

Jakub Narębski answered 2020-07-31T09:52:14Z
6 votes

git reset X将分支引用设置为给定的哈希,并选择使用topic2将其检出。

git reset X将工作树设置为给定的哈希值; 除非哈希是分支名称,否则您将以一个独立的头结尾。

最终,git处理了三件事:

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

默认情况下git reset X仅更新索引和工作树,并且可以选择更新存储库中的某些内容(使用topic2选项)

git reset X默认情况下仅更新存储库和索引,以及可选的工作树(带有topic2选项)

您可以这样考虑存储库:

 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 X处理分支引用所指向的内容。

假设您的历史记录如下:

           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

您当前的分支是git reset X,也就是说,HEAD指向topic2。

HEAD -> topic2

然后,git reset X会将名称topic2重置为指向X; 这意味着,如果您在分支topic2上进行提交P,则情况将如下所示:

           T--S--R--Q [master][dev]
          / 
   A--B--C--D--E--F--G [topic1]
                   \
                    Z--Y--X--W [topic3]
                           \
                            P [topic2]
hasen answered 2020-07-31T09:53:23Z
translate from https://stackoverflow.com:/questions/2541545/is-there-a-difference-between-git-reset-hard-hash-and-git-checkout-hash