我一直认为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-ground-up/using-git-cherry-pick-to-simulate-git-rebase.html中 ,结帐和重置可以模拟变基。
git checkout bar
git reset --hard newbar
git branch -d newbar
#1楼
Atlassian为我们提供了有关git reset , git checkout等的出色解释,因此git revert 。 在本文中,将解释这些命令在不同级别上的不同用法-文件,暂存快照和提交。
https://www.atlassian.com/git/tutorials/resetting-checking-out-and-reverting
#2楼
这两个命令(重置和签出)完全不同。
checkout X
不会reset --hard X
如果X是分支名称,则checkout X
将更改当前分支,而reset --hard X
不会。
#3楼
还原更改时的一个简单用例:
1.如果要撤消已修改文件的暂存,请使用reset。
2.如果要放弃对未暂存文件的更改,请使用checkout。
#4楼
-
git reset
专门用于更新索引 ,移动HEAD。 -
git checkout
与更新工作树 (到索引或指定的树)有关。 仅当您签出分支时,它才会更新HEAD(否则,您将获得一个分离的HEAD )。
(实际上,在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也具有index的概念(存储库和工作树之间的“临时区域”),因此您也需要git reset
。
Thinkeye 在评论中提到了 “ Reset Demystified ”一词。
例如,如果我们有两个分支,分别指向不同的提交的“
master
”和“develop
”,而我们当前处于“develop
”(因此HEAD指向它),并且我们运行git reset master
,则“develop
”本身现在将指向与“master
”相同的提交。另一方面,如果我们改为运行
git checkout master
,则'develop
'将不会移动,而HEAD
本身会移动。HEAD
现在将指向“master
”。因此,在两种情况下,我们都将
HEAD
指向提交A
,但是我们的做法却大不相同。reset
将把分支HEAD
指向,结帐将HEAD
本身指向另一个分支。

但是,在这些方面:
但是,此答案的第一段是令人误解的:“
git checkout
...仅当您签出一个分支时才会更新HEAD(否则,您将得到一个分离的HEAD)”。
不正确:即使您检出不是分支的提交,git checkout
也会更新HEAD(是的,您最终得到一个分离的HEAD,但它仍得到更新)。git checkout a839e8f updates HEAD to point to commit a839e8f.
@LarsH是正确的。
第二个项目符号对HEAD的含义有误解,只有在签出分支后才会更新HEAD。
HEAD随处可见,就像阴影一样。
检出一些非分支引用(例如,标记)或直接提交,将移动HEAD。 分离的head并不意味着您已经与HEAD分离,这意味着head与分支ref分离了,例如,您可以从git log --pretty=format:"%d" -1
看到。
- 附加的头部状态将以
(HEAD ->
,- detached仍将显示
(HEAD
,但没有指向分支引用的箭头。
#5楼
以其最简单的形式, 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
),但是它将始终将提供的路径的索引版本检出到工作树中。
来源:oschina
链接:https://my.oschina.net/stackoom/blog/3162718