虽然reset
和checkout
大多数时候有不同的用法,但我不明白这两者之间有什么区别。“git reset --hard hash”和“git checkout hash”有区别吗?
有可能是一个或没有人会打扰增加一个--hard
选项来做一些基本的checkout
可以做的事情。
也许有区别是你会看到历史的方式?
虽然reset
和checkout
大多数时候有不同的用法,但我不明白这两者之间有什么区别。“git reset --hard hash”和“git checkout hash”有区别吗?
有可能是一个或没有人会打扰增加一个--hard
选项来做一些基本的checkout
可以做的事情。
也许有区别是你会看到历史的方式?
这个答案大多是从我对前一个问题的回答引用的:git reset in plain english。
这两者非常不同。它们导致索引和工作树的状态相同,但生成的历史和当前分支不相同。
假设你的历史看起来像这样,与当前已签出master分支:
- 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
过你会真正得到这种效果 - 唯一的区别是发生了什么你的工作树和索引。在--hard
的情况下,工作树和索引匹配B
。
现在,假设您将运行git checkout B
。你会得到这个:
- A - B (HEAD) - C (master)
你已经结束了分离HEAD状态。 HEAD
,工作树,索引全部匹配B
,与硬重置相同,但主分支留在C
。如果您在这一点上新的提交D
,你会得到这一点,这可能不是你想要的东西:
- A - B - C (master)
\
D (HEAD)
因此,您使用结账时,好了,检查出承诺。你可以摆弄它,做你喜欢的事,但是你已经把你的分支留下了。如果您希望分支也移动,则使用重置。
如果Git提供的文档不能帮助您,请查看Mark Lodato的A Visual Git Reference。
特别是如果你是比较git checkout <non-branch>
与git reset --hard <non-branch>
(热链接):
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
将分支引用设置为给定的散列,并且可以选择将其检出,并使用--hard
。
git-checkout hash
将工作树设置为给定散列;除非散列是一个分支名称,否则最终会有一个分离的头部。
最终,有三件事情git的交易:
working tree (your code)
-------------------------------------------------------------------------
index/staging-area
-------------------------------------------------------------------------
repository (bunch of commits, trees, branch names, etc)
git-checkout
默认情况下只更新索引和工作树,可以选择更新的档案库里的东西(与-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
,即,头指向标题2。
HEAD -> topic2
然后,git reset X
将重置名称topic2
指向X;这意味着,如果你犯了一个提交的分支标题2 P,事情会是这样的:
T--S--R--Q [master][dev]
/
A--B--C--D--E--F--G [topic1]
\
Z--Y--X--W [topic3]
\
P [topic2]
我介绍了这个在更新到我的回答对你以前的问题之一 - 看看ASCII艺术上方附近,特别是在它说:“Digression:...”(尽可能多我喜欢更多的代表在这里重新回答它) – Cascabel 2010-03-29 22:02:40
我认为你可以在这里发布你的答案,并从中获得代表。如果有人搜索这个特定的知识,他不会找到其他职位。这一个目标是一个非常具体的主题,它应该拥有独立的页面。顺便说一句,看来你是我的Git导师:-) harigato,senseï! – 2010-03-29 22:10:40
但是我得到它,区别在于重置移动分支而不是结帐。 – 2010-03-29 22:12:05