git reset --hard和git checkout的区别

10

假设我想撤销之前提交的所有更改。

就我所知,git reset --hard <指定的提交> 将删除指定提交之前的所有提交,并撤消所有更改。
另一方面, git checkout <指定的提交> 会更改我的目录以反映指定的提交。

那么如果我在 git checkout 后执行 git reset ,它是否会产生与 git reset --hard 相同的结果?

或者,如果我仅在 git checkout 后执行 git commit,新创建的提交是否会覆盖现有的提交?


如果您在检出后提交,您将得到一个分支点,而不是覆盖。 - Ôrel
2个回答

12

提交是树形结构,分支是指向某些提交的指针,而 HEAD(别名:@)是指向某个分支或某个提交的指针(“游离的 HEAD”)。

git checkout <commit> 命令将HEAD、索引和工作目录移到指定的提交,并在可能情况下保留索引和工作目录中的本地更改,否则此操作将中止。这时,HEAD变成了游离状态。您将看到这条消息,它很容易理解:

您处于“游离的 HEAD”状态。您可以四处查看,进行实验性更改并提交它们,您可以通过执行另一个checkout命令丢弃在此状态下所做的任何提交,而不会影响任何分支。

如果您想创建一个新分支来保留您创建的提交,则可以使用 checkout 命令再次使用 -b。例如:

git checkout -b new_branch_name

因此,您不会失去工作目录和索引中的任何更改也不会失去任何提交。* 这是一个安全的操作。

git reset --hard <commit> 命令将HEAD指向的分支或者游离状态下的 HEAD、索引和工作目录移到指定的提交。所以,您会失去工作目录和索引中的所有更改。此外,如果您要移动到一些旧的提交,并且较新的提交不在其他分支中,您也将失去这些较新的提交。这是不安全的操作,除非您真正理解您在做什么,请勿执行此操作。

请参考这些优秀的答案,了解如何撤销提交。

您还可以使用 SourceTree 等图形用户界面工具来帮助您。


* 除非您已经处于一些悬空提交的分离HEAD状态,否则通常您不必担心。


3
如果我在git checkout之后进行git reset,结果会与git reset --hard相同吗?
不会。git reset(带--hard或任何其他选项)会重置HEAD,因此您始终会丢失提交,除非您未指定要重置的任何提交。
在执行git checkout 之后,您处于分离的HEAD状态,因此git reset有点无意义,因为您不会重置任何分支。
或者,如果我只是在git checkout之后简单地进行git commit,新创建的提交是否会覆盖现有的提交?
不会。因为再次,您处于分离的HEAD状态。实际上,您正在一个幽灵分支中创建提交。
最安全的方法是始终使用git checkout -b创建新分支,一旦确定要重置其他分支,然后执行git reset --hard。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接