“git reset --hard hash” 和 “git reset --hard hash” 之间有区别吗?和“git checkout 哈希”?
虽然 reset
和 checkout
大多数时候都有不同的用法,但我看不出这两者之间有什么区别。
可能有人或没有人愿意添加一个 --hard
选项来完成基本的 checkout
可以做的事情。
也许你们看待历史的方式有所不同?
While reset
and checkout
have different usages most of the time, I can't see what difference there is between these two.
There probably is one or nobody would have bothered adding a --hard
option to do something the basic checkout
can do.
Maybe there is a difference is the way you will see the history?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这个答案主要引用自我对上一个问题的回答: 用简单的英语重置 git。
两者非常不同。它们会导致索引和工作树处于相同的状态,但生成的历史记录和当前分支并不相同。
假设您的历史记录如下所示,当前已签出 master 分支:
并且您运行 git reset --hard B 。你会得到这样的结果:
如果你也使用
--mixed
或--soft
,你实际上会得到这样的效果 - 唯一的区别是你的工作树和指数。在--hard
情况下,工作树和索引与B
匹配。现在,假设您改为运行 git checkout B 。你会得到这样的结果:
你最终处于分离的 HEAD 状态。
HEAD
、工作树、索引都匹配B
,与硬重置相同,但主分支留在了C
。如果您此时进行新的提交D
,您将得到这个,这可能不是您想要的:因此,您使用 checkout 来检查该提交。你可以摆弄它,做你喜欢做的事,但你已经把你的分支抛在后面了。如果您希望分支也移动,请使用重置。
This answer is mostly quoted from my answer to a previous question: git reset in plain english.
The two are very different. They result in the same state for your index and work tree, but the resulting history and current branch aren't the same.
Suppose your history looks like this, with the master branch currently checked out:
and you run
git reset --hard B
. You'll get this:You'd actually get that effect if you use
--mixed
or--soft
too - the only difference is what happens to your work tree and index. In the--hard
case, the work tree and index matchB
.Now, suppose you'd run
git checkout B
instead. You'd get this:You've ended up in a detached HEAD state.
HEAD
, work tree, index all matchB
, same as with the hard reset, but the master branch was left behind atC
. If you make a new commitD
at this point, you'll get this, which is probably not what you want:So, you use checkout to, well, check out that commit. You can fiddle with it, do what you like, but you've left your branch behind. If you want the branch moved too, you use reset.
如果 Git 提供的文档对您没有帮助,请查看可视化 Git 参考 马克·洛达托。
特别是如果您将 git checkout与
git reset --hard
(热链接)进行比较:< /a>
(来源:github.com)
请注意,在
git reset --hard master~3
的情况下,您会留下修订 DAG 的一部分 - 一些提交不被任何分支引用。这些内容受到reflog的保护(默认情况下)30天;它们最终将被修剪(移除)。If documentation provided with Git doesn't help you, take a look at A Visual Git Reference by Mark Lodato.
In particular if you are comparing
git checkout <non-branch>
withgit reset --hard <non-branch>
(hotlinked):(source: github.com)
Note that in the case of
git reset --hard master~3
you leave behind a part of DAG of revisions - some of commits are not referenced by any branch. Those are protected for (by default) 30 days by reflog; they would ultimately be pruned (removed).git-reset hash
将分支引用设置为给定的哈希,并可以选择使用--hard
将其检出。git-checkout hash
将工作树设置为给定的哈希值;除非 hash 是分支名称,否则您最终会得到一个分离的头。最终,git 处理三件事:
git-checkout
默认情况下只更新索引和工作树,并且可以选择更新存储库中的某些内容(使用-b
选项) )默认情况下,
git-reset
仅更新存储库和索引,以及可选的工作树(使用--hard
选项)您可以将存储库视为如下:
git-reset 操纵分支引用指向的内容。
假设您的历史记录如下所示:
请记住,分支只是您提交时自动前进的名称。
所以你有以下分支:
而你当前的分支是
topic2
,即HEAD指向topic2。然后,
git reset X
将重置名称topic2
以指向X;这意味着如果您在分支 topic2 上提交 P,事情将如下所示:git-reset hash
sets the branch reference to the given hash, and optionally checks it out, with--hard
.git-checkout hash
sets the working tree to the given hash; and unless hash is a branch name, you'll end up with a detached head.ultimately, git deals with 3 things:
git-checkout
by default just updates the index and the working tree, and can optionally update something in the repository (with the-b
option)git-reset
by default just updates the repository and the index, and optionally the working tree (with the--hard
option)You can think of the repository like this:
git-reset
manipulates what the branch references point to.Suppose your history looks like this:
Keep in mind that branches are just names that advance automatically when you commit.
So you have the following branches:
And your current branch is
topic2
, that is, the HEAD points to topic2.Then,
git reset X
will reset the nametopic2
to point to X; meaning if you make a commit P on branch topic2, things will look like this: