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

添加

Vonc和Charles解释了 git resetgit checkout 真的很好。我目前的理解是 git reset 将所有更改都恢复为特定的提交,而 git checkout 或多或少为分支做准备。我发现以下两个图在了解这一理解方面非常有用:

http://a.imageshack.us/img651/1559/86421927.png http://a.imageshack.us/img801/1986/resetr.png

添加了3

http://think-like-a-git.net/sections/rebase-from-the-gound-ump/using-git-cherry-pick-to-simute-git-rebase.html, ,结帐和重置可以模仿反弹。

enter image description here

git checkout bar 
git reset --hard newbar 
git branch -d newbar 

enter image description here

有帮助吗?

解决方案

  • 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.


Thinkeye 提及 在评论中 这篇文章”重置神秘 ".

例如,如果我们有两个分支,master' 和 'develop“指向不同的提交,我们目前正在进行”develop'(所以指向它),我们运行 git reset master, 'develop“本身将指出同样的承诺”master' 做。

另一方面,如果我们运行 git checkout master, 'develop'不会移动, HEAD 本身会。 HEAD 现在将指向master'.

因此,在这两种情况下,我们都在移动 HEAD 指出提交 A, ,但是我们这样做是非常不同的。 reset 将移动分支 HEAD 指向,结帐移动 HEAD 本身指向另一个分支。

http://git-scm.com/images/reset/reset-checkout.png

但是,这些要点:

拉什 添加 在评论中:

但是,这个答案的第一段是误导的:”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 以及给定提交的索引以及将索引的结帐到工作树中。

另外,如果您提供 --hardreset 你可以问 reset 覆盖工作树以及重置索引。

如果您目前有一个分支,请签到 resetcheckout 当您提供替代分支或提交时。 reset 将把当前分支更改为指向选定的提交,而 checkout 将使当前的分支单独放置,但会结帐所提供的分支或提交。

其他形式 resetcommit 涉及提供路径。

如果您提供通往的路 reset 您无法供应 --hardreset 只会将提供的路径的索引版本更改为所提供的提交中的版本(或 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的答案 非常有用的文字和图摘录 从同一篇文章中,我不会在这里复制。

当然,还有很多有关效果的细节 checkoutreset 根据使用了哪些参数,可以在索引和工作树上具有。两个命令之间可能存在很多相似之处和差异。但是,正如我所看到的,最关键的差异是它们是否移动当前分支的尖端。

这两个命令(重置和结帐)是完全不同的。

checkout X 不是 reset --hard X

如果x是分支名称,checkout X 将改变当前分支 reset --hard X 将不会。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top