“ Git Reset”和“ Git Checkout”有什么区别?
-
30-09-2019 - |
题
我一直想到 git reset
和 git checkout
同样,从两者都将项目带回特定的提交的意义上。但是,我觉得它们不能完全一样,因为那是多余的。两者之间的实际区别是什么?我有点困惑,因为SVN只有 svn co
恢复提交。
添加
Vonc和Charles解释了 git reset
和 git checkout
真的很好。我目前的理解是 git reset
将所有更改都恢复为特定的提交,而 git checkout
或多或少为分支做准备。我发现以下两个图在了解这一理解方面非常有用:
添加了3
从 http://think-like-a-git.net/sections/rebase-from-the-gound-ump/using-git-cherry-pick-to-simute-git-rebase.html, ,结帐和重置可以模仿反弹。
git checkout bar
git reset --hard newbar
git branch -d newbar
解决方案
git reset
特别是关于 更新索引, ,移动头部。git checkout
是关于 更新工作树 (到索引或指定的树)。仅当您结帐分支时,它才会更新头(如果没有的话,您最终都会有一个 脱落的头).
(实际上,与GIT 2.23 Q3 2019一起,这将是git restore
, , 不必要git checkout
)
相比之下,由于SVN没有索引,只有一棵工作的树, svn checkout
将在单独的目录上复制给定的修订。
相当于 git checkout
将:
svn update
(如果您在同一分支中,则表示相同的SVN URL)svn switch
(如果您结帐相同的分支,但从另一个SVN回购URL)
这三个工作树修改(svn checkout
, update
, switch
)在git中只有一个命令: git checkout
.
但是,由于git也有索引的概念(在存储库和工作树之间的“登台区域”),所以您也有 git reset
.
例如,如果我们有两个分支,
master
' 和 'develop
“指向不同的提交,我们目前正在进行”develop
'(所以指向它),我们运行git reset master
, 'develop
“本身将指出同样的承诺”master
' 做。另一方面,如果我们运行
git checkout master
, 'develop
'不会移动,HEAD
本身会。HEAD
现在将指向master
'.因此,在这两种情况下,我们都在移动
HEAD
指出提交A
, ,但是我们这样做是非常不同的。reset
将移动分支HEAD
指向,结帐移动HEAD
本身指向另一个分支。
但是,这些要点:
但是,这个答案的第一段是误导的:”
git checkout
...仅当您结帐分支(如果没有)时,才会更新头部。
不对:git checkout
即使您结帐了不是分支机构的提交(是的,您最终都会有一个独立的头部,但仍会更新)。git checkout a839e8f updates HEAD to point to commit a839e8f.
@larsh是正确的。
第二个子弹对什么头部有一个误解,只有在您结帐分支时,才会更新头部。
头部无论您身在何处,都像阴影一样。
查看一些非分支ref(例如,标签)或直接提交将移动头部。独立的头部并不意味着您已经从头部分离了,这意味着头部与分支ref分离,您可以从中看到,例如,git log --pretty=format:"%d" -1
.
- 附属的头态将以
(HEAD ->
,- 独立的仍将显示
(HEAD
, ,但不会有分支参考的箭头。
其他提示
以最简单的形式 reset
重置索引而无需触摸工作树,而 checkout
更改工作树而无需触摸索引。
重置索引以匹配 HEAD
, ,独自工作的工作树:
git reset
从概念上讲,这将检查到工作树中的索引。为了让它实际做任何您必须使用的任何事情 -f
强迫它覆盖任何本地变化。这是一个安全功能,以确保“无参数”表格不会破坏:
git checkout
一旦开始添加参数,确实存在一些重叠。
checkout
通常与分支,标签或提交一起使用。在这种情况下,它将重置 HEAD
以及给定提交的索引以及将索引的结帐到工作树中。
另外,如果您提供 --hard
到 reset
你可以问 reset
覆盖工作树以及重置索引。
如果您目前有一个分支,请签到 reset
和 checkout
当您提供替代分支或提交时。 reset
将把当前分支更改为指向选定的提交,而 checkout
将使当前的分支单独放置,但会结帐所提供的分支或提交。
其他形式 reset
和 commit
涉及提供路径。
如果您提供通往的路 reset
您无法供应 --hard
和 reset
只会将提供的路径的索引版本更改为所提供的提交中的版本(或 HEAD
如果您不指定提交)。
如果您提供通往的路 checkout
, , 像 reset
它将更新提供的路径的索引版本以匹配所提供的提交(或 HEAD
)但是,它将始终检查到工作树中提供的路径的索引版本。
重新更改时一种简单的用例:
1.如果要撤消修改后的文件,请使用重置。
2.如果要丢弃对未分段的文件/s的更改,请使用结帐。
阿特拉斯利亚人 给我们一个很好的解释 git重置, GIT结帐 所以, git恢复. 。在本文中,解释了这些命令在不同级别上的不同用途 - 文件,上演快照和提交。
https://www.atlassian.com/git/tutorials/resetting-checking-und-and-reverting
简而言之的关键区别在于 reset
移动当前分支参考, , 尽管 checkout
不(它移动)。
正如专业书籍所解释的那样 重置神秘,
第一件事
reset
会做 移动什么头指向. 。这与 改变头部 (这就是什么checkout
做);reset
移动分支 那个头指的是。这意味着如果头设置为master
分支(即您目前正在master
分支),运行git reset 9e5e6a4
从制作开始master
指向9e5e6a4
. 。 [添加了强调
另请参阅VONC的答案 非常有用的文字和图摘录 从同一篇文章中,我不会在这里复制。
当然,还有很多有关效果的细节 checkout
和 reset
根据使用了哪些参数,可以在索引和工作树上具有。两个命令之间可能存在很多相似之处和差异。但是,正如我所看到的,最关键的差异是它们是否移动当前分支的尖端。
这两个命令(重置和结帐)是完全不同的。
checkout X
不是 reset --hard X
如果x是分支名称,checkout X
将改变当前分支 reset --hard X
将不会。