【问题标题】:Difference between git reset --hard and git checkoutgit reset --hard 和 git checkout 的区别
【发布时间】:2015-08-26 15:01:58
【问题描述】:

假设我想撤消以前提交引入的所有更改。

据我了解,git reset --hard <specified commit> 将删除直到指定提交之前的所有提交,并撤消所有更改。
另一方面,git checkout <specified commit> 将更改我的目录以反映指定的提交。

那么如果我在git checkout 之后git reset 会得到与git reset --hard 相同的结果吗?

或者,如果我在git checkout 之后简单地git commit,新创建的提交会覆盖现有提交吗?

【问题讨论】:

  • 如果您在结帐后提交,您将是一个分支点,而不是覆盖。

标签: git version-control git-checkout git-reset


【解决方案1】:

简而言之,git 提交是一棵树,分支只是指向某些提交的指针。

git checkout <specified commit> 不移动分支指针。当你这样做时,你处于分离的头部状态。您将看到这条消息,它非常不言自明:

您处于“分离 HEAD”状态。你可以环顾四周,制作 实验性更改并提交它们,您可以丢弃任何提交 你在这个状态下通过执行不影响任何分支 另一个结帐。

如果你想创建一个新分支来保留你创建的提交,你 可以通过再次使用 -b 和 checkout 命令来这样做(现在或以后)。 示例:

git checkout -b new_branch_name

另一个区别是git checkout 更安全,因为它不会拒绝您在工作树中的更改,并且您不会丢失任何提交¹。

另一方面,

git reset --hard <specified commit> 会将您当前的分支移动到指定的提交,并且您将丢失工作树中的所有更改。此外,如果您要转移到某个较旧的提交,而较新的提交不在某个其他分支中,您也会丢失这些较新的提交。这不是一个安全的操作,除非您真正了解自己在做什么,否则不要这样做。

有关如何撤消 git 提交的信息,另请参阅 these great answers

您还可以从使用 SourceTree 等 GUI 工具中受益。


¹ - 好吧,除非你已经在某个悬空提交中处于分离的头部状态,但通常你不应该担心。

【讨论】:

    【解决方案2】:

    那么如果我在git checkout 之后git reset 会得到与git reset --hard 相同的结果吗?

    没有。 git reset(使用 --hard 或任何其他选项)重置 HEAD,因此您总是会丢失提交,除非您没有指定任何要重置的提交。

    在您执行git checkout <commit> 之后,您处于分离的HEAD 状态,因此git reset 有点毫无意义,因为您不会重置任何分支。

    或者,如果我在git checkout 之后简单地git commit,新创建的提交会覆盖现有提交吗?

    没有。因为再次,您处于分离的 HEAD 状态。您实际上是在幽灵分支中创建提交。

    最安全的做法是始终使用git checkout -b 创建一个新分支,一旦您确定要重置另一个分支,然后执行git reset --hard

    【讨论】:

      猜你喜欢
      • 2015-11-20
      • 2011-02-02
      • 2017-12-10
      • 2011-09-06
      • 2011-07-04
      • 2020-04-07
      • 2015-08-26
      • 1970-01-01
      • 2011-04-08
      相关资源
      最近更新 更多