“git reset –hard hash”和“git checkout hash”有区别吗?

虽然大多数时候resetcheckout有不同的用法,但是我看不出这两者之间有什么区别。

可能有一个,或者没有人会join一个 – --hard选项来做一些基本的checkout

也许有什么不同,你会看到历史的方式?

这个答案大部分是从我对前一个问题的回答中引用的: git reset in plain english 。

这两个是非常不同的。 它们导致您的索引和工作树处于相同的状态,但生成的历史logging和当前分支不一样。

假设您的历史logging如下所示,主分支目前已经签出:

 - 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 ,你会得到这个效果 – 唯一的区别是你的工作树和索引会发生什么。 在这种情况下,工作树和索引匹配B

现在,假设你会运行git checkout B 你会得到这个:

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

你已经结束了一个分离的HEAD状态。 HEAD ,工作树,索引全部匹配B ,与硬重置相同,但主分支留在C 。 如果你现在做了一个新的提交D ,你会得到这个,这可能不是你想要的:

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

所以,你使用checkout来检查那个提交。 你可以捣鼓它,做你喜欢的,但是你把你的分支留下了。 如果你想分支也移动,你使用重置。

如果Git提供的文档不能帮助您,请参阅Mark Lodato的“ Visual Git参考” 。

特别是如果你比较git checkout <non-branch>git reset --hard <non-branch> (hotlinked):

git checkout master〜3 http://marklodato.github.com/visual-git-guide/checkout-detached.svg.png

git reset –hard master〜3 http://marklodato.github.com/visual-git-guide/reset-commit.svg.png

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

git-reset hash将分支引用设置为给定的哈希值,并且可以select使用--hard进行检查。

git-checkout hash将工作树设置为给定的散列值; 除非散列是一个分支的名字,否则你会得到一个分离的头。

最终,git处理3件事情:

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

git-checkout默认只是更新索引和工作树,并且可以select更新仓库中的某些东西(带-b选项)

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

你可以这样想:

  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 ,也就是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]