处于分离HEAD状态下的'git commit --amend'

17

我知道修改旧Git提交的正确方法是使用rebase --interactive,但为了更清楚地理解概念,我想了解当我执行以下操作时会发生什么:

  • git checkout <commit>
  • 更改文件中的某些内容
  • 将更改的文件添加到索引中
  • 然后执行git commit . --amend

当我这样做时,它不是修改提交,而是在该提交的父级上创建一个新提交。

这只是Git告诉我不能修改已经有子提交的提交吗?

1个回答

32
在Git中,一旦创建了提交,它就是不可更改的。你所能做的——通过修订、挑选等——只是创建一个新的提交,使其“类似于”原始提交。
我理解你的困惑:“修订”有点不准确; 它有些误导性,因为它暗示着在原地修改某些内容。在Git中,“修订提交”实际上是创建一个全新的提交,该提交具有与原始提交相同的父级。
例如,假设在运行git checkout B后,您处于以下情况:

enter image description here

(你的 HEAD 已经分离,但这并不是重点。) 无论你是否进行更改和暂存,运行 git commit --amend 都会让你处于这种情况:

enter image description here

提交 D 可能与 B 非常相似;特别是,它可能具有完全相同的补丁、完全相同的提交信息等。然而,(提交、作者)时间戳通常会不同(除非您可以在一秒内修改提交!),这意味着 D 的 SHA-1 与 B 的 SHA-1 不同;如果两个提交的 SHA-1 不同,它们就不是同一个提交。

当我们说BC的父提交时,我们指的是C通过其SHA引用了B提交。 然而,C提交无法知道D提交的SHA,因为D提交是在C提交之后创建的。因此,D不能成为C的父提交。这就是为什么D提交会走向一个分支,并且没有任何后代的原因。
如果您想降落在以下状态,请使用:

enter image description here

如果B'B只有轻微的不同,您应该使用git rebase -i而不是git commit --amend


2
非常好的回答。谢谢! 我完全没意识到 --amend 命令总是从 HEAD 的父分支开始。现在想起来,这就很有道理了。 - Chris

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