“git reset"和“git reset"有什么区别?和“git checkout"? [英] What's the difference between "git reset" and "git checkout"?

查看:52
本文介绍了“git reset"和“git reset"有什么区别?和“git checkout"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直认为 git resetgit checkout 是一样的,因为两者都将项目带回特定的提交.但是,我觉得它们不能完全相同,因为那是多余的.两者之间的实际区别是什么?我有点困惑,因为 svn 只有 svn co 来恢复提交.

添加

VonC 和 Charles 很好地解释了 git resetgit checkout 之间的区别.我目前的理解是 git reset 将所有更改还原回特定的提交,而 git checkout 或多或少地为分支做准备.我发现以下两个图表非常有助于理解这一点:

添加了 3 个

来自

git 结帐栏git reset --hard newbargit branch -d newbar

解决方案

  • 尽管如此:

    LarsH 添加了 在评论中:

    <块引用>

    然而,这个答案的第一段具有误导性:"git checkout ... 仅当您结帐分支时才会更新 HEAD(如果没有,您最终会得到一个分离的 HEAD)".
    不正确:git checkout 会更新 HEAD,即使你签出一个不是分支的提交(是的,你最终得到了一个分离的 HEAD,但它仍然得到了更新).

    git checkout a839e8f 更新 HEAD 以指向提交 a839e8f.

    De Novo 同意 在评论中:

    <块引用>

    @LarsH 是正确的.
    第二个项目符号对 HEAD 的内容存在误解,只有在您签出分支时才会更新 HEAD.
    HEAD 无处不在,就像影子一样.
    检出一些非分支引用(例如,标签),或直接提交,将移动 HEAD.分离的头部并不意味着你已经与头部分离,这意味着头部与分支引用分离,你可以从例如 git log --pretty=format:"%d" 中看到.-1.

    • 附加的头部状态将以 (HEAD ->,
    • detached 仍会显示 (HEAD,但不会有指向分支引用的箭头.

    I've always thought of git reset and git 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 has svn co to revert the commit.

    ADDED

    VonC and Charles explained the differences between git reset and git checkout really well. My current understanding is that git reset reverts all of the changes back to a specific commit, whereas git 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 be git restore, not necessarily git 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 for git 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 have git 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 run git 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 commit A, but how we do so is very different. reset will move the branch HEAD points to, checkout moves HEAD 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆