“git reset"和“git reset"有什么区别?和“git checkout"? [英] What's the difference between "git reset" and "git checkout"?
问题描述
我一直认为 git reset
和 git checkout
是一样的,因为两者都将项目带回特定的提交.但是,我觉得它们不能完全相同,因为那是多余的.两者之间的实际区别是什么?我有点困惑,因为 svn 只有 svn co
来恢复提交.
添加
VonC 和 Charles 很好地解释了 git reset
和 git checkout
之间的区别.我目前的理解是 git reset
将所有更改还原回特定的提交,而 git checkout
或多或少地为分支做准备.我发现以下两个图表非常有助于理解这一点:
添加了 3 个
来自
git 结帐栏git reset --hard newbargit branch -d newbar
尽管如此:
<块引用>然而,这个答案的第一段具有误导性:"
git checkout
... 仅当您结帐分支时才会更新 HEAD(如果没有,您最终会得到一个分离的 HEAD)".
不正确:git checkout
会更新 HEAD,即使你签出一个不是分支的提交(是的,你最终得到了一个分离的 HEAD,但它仍然得到了更新).
<块引用>git checkout a839e8f 更新 HEAD 以指向提交 a839e8f.
@LarsH 是正确的.
第二个项目符号对 HEAD 的内容存在误解,只有在您签出分支时才会更新 HEAD.
HEAD 无处不在,就像影子一样.
检出一些非分支引用(例如,标签),或直接提交,将移动 HEAD.分离的头部并不意味着你已经与头部分离,这意味着头部与分支引用分离,你可以从例如git log --pretty=format:"%d" 中看到.-1
.- 附加的头部状态将以
(HEAD ->
, - detached 仍会显示
(HEAD
,但不会有指向分支引用的箭头.
I've always thought of
git reset
andgit checkout
as the same, in the sense that both bring the project back to a specific commit. However, I feel they can't be exactly the same, as that would be redundant. What is the actual difference between the two? I'm a bit confused, as the svn only hassvn co
to revert the commit.ADDED
VonC and Charles explained the differences between
git reset
andgit checkout
really well. My current understanding is thatgit reset
reverts all of the changes back to a specific commit, whereasgit checkout
more or less prepares for a branch. I found the following two diagrams quite useful in coming to this understanding:ADDED 3
From http://think-like-a-git.net/sections/rebase-from-the-ground-up/using-git-cherry-pick-to-simulate-git-rebase.html, checkout and reset can emulate the rebase.
git checkout bar git reset --hard newbar git branch -d newbar
解决方案git reset
is specifically about updating the index, moving the HEAD.git checkout
is about updating the working tree (to the index or the specified tree). It will update the HEAD only if you checkout a branch (if not, you end up with a detached HEAD).
(actually, with Git 2.23 Q3 2019, this will begit restore
, not necessarilygit checkout
)
By comparison, since svn has no index, only a working tree,
svn checkout
will copy a given revision on a separate directory.
The closer equivalent forgit checkout
would:svn update
(if you are in the same branch, meaning the same SVN URL)svn switch
(if you checkout for instance the same branch, but from another SVN repo URL)
All those three working tree modifications (
svn checkout
,update
,switch
) have only one command in git:git checkout
.
But since git has also the notion of index (that "staging area" between the repo and the working tree), you also havegit reset
.
Thinkeye mentions in the comments the article "Reset Demystified ".
For instance, if we have two branches, '
master
' and 'develop
' pointing at different commits, and we're currently on 'develop
' (so HEAD points to it) and we rungit reset master
, 'develop
' itself will now point to the same commit that 'master
' does.On the other hand, if we instead run
git checkout master
, 'develop
' will not move,HEAD
itself will.HEAD
will now point to 'master
'.So, in both cases we're moving
HEAD
to point to commitA
, but how we do so is very different.reset
will move the branchHEAD
points to, checkout movesHEAD
itself to point to another branch.On those points, though:
LarsH adds in the comments:
The first paragraph of this answer, though, is misleading: "
git checkout
... will update the HEAD only if you checkout a branch (if not, you end up with a detached HEAD)".
Not true:git checkout
will update the HEAD even if you checkout a commit that's not a branch (and yes, you end up with a detached HEAD, but it still got updated).git checkout a839e8f updates HEAD to point to commit a839e8f.
De Novo concurs in the comments:
@LarsH is correct.
The second bullet has a misconception about what HEAD is in will update the HEAD only if you checkout a branch.
HEAD goes wherever you are, like a shadow.
Checking out some non-branch ref (e.g., a tag), or a commit directly, will move HEAD. Detached head doesn't mean you've detached from the HEAD, it means the head is detached from a branch ref, which you can see from, e.g.,git log --pretty=format:"%d" -1
.- Attached head states will start with
(HEAD ->
, - detached will still show
(HEAD
, but will not have an arrow to a branch ref.
这篇关于“git reset"和“git reset"有什么区别?和“git checkout"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- 附加的头部状态将以