Git rebase -i HEAD~n 不工作

Ser*_*gio 6 git rebase

我正在尝试编辑已推送的提交消息。
我正在遵循这些基本上是 Rebase → Reword → Push 的步骤。

问题是git rebase -i HEAD~3它不仅显示最后 3 次提交,还显示最后 20 次提交!即使我这样做了,git rebase -i <commit_hash>我也会显示 20 个提交。我究竟做错了什么?

Dan*_*osh 1

在给出答案之前,我应该先警告一下:无论你如何做,编辑提交消息都涉及重写git 中的历史记录。对于您已推送到其他人可能签出或在其上工作的分支的提交,这不是您应该做的事情(例如master)。一旦你将提交推送到像 master 这样的分支,你应该考虑这些提交是永久的/一成不变的。除非你有一个非常充分的理由(例如,你推送了一个包含安全敏感内容(如你的私有 ssh 密钥)的提交),否则你不应该重写该历史记录。

其次,这不会解决您的问题,但是假设指的<commit_hash>是您要编辑的提交的哈希值,git rebase -i <commit_hash>这是不正确的。您链接的说明中给出的正确版本实际上是git rebase -i <commit_hash>^(请注意^最后的)。Rebase 不包含您传递的参数,因此如果您想编辑<commit_hash>,则必须传递给 rebase 的提交是之前的提交(即<commit_hash>^)。


正如 @Sergio 提到的,造成这种情况的原因可能是最近 3 次提交中的合并提交。由于多种原因,Rebase 不能很好地处理合并提交。

虽然对合并提交进行变基并非不可能,但没有一种明确、合理的方法可以做到这一点,因此有几种不同的选项可以告诉 git 如何做到这一点。此外,rebase 合并提交的过程还存在许多微妙的复杂性,如果您不熟悉 git,可能会有点难以解释。

如果您没有足够的知识来弄清楚如何从 git 文档中做到这一点,我建议您做的是更手动的等效操作:

  1. 标记您当前的提交,以防您犯了错误并需要恢复或重新开始:git tag temp。另外,当您执行此操作时,请使用以下命令检查是否有任何未暂存或未提交的更改git status
  2. 重置为您要编辑消息的提交:git reset --hard HEAD~3
  3. 编辑提交消息git commit --amend
  4. 使用更新的提交消息在新的、修改的提交之上重新创建其他更改。对于非合并提交,您可以使用cherry-pick 来复制它们。对于合并提交,您必须git merge像第一次创建它们时一样重新进行操作。如果有冲突,重新解决。如果合并包括一些手动修改,您也需要重新进行这些修改。
  5. git diff temp使用和仔细检查结果git range-diff HEAD...temp。如果不正确,或者在该过程中的任何时刻您意识到自己犯了错误,您可以重新开始git reset --hard temp
  6. 推送您的更改:(git push --force-with-lease--force-with-lease更安全的替代方案--force
  7. 如果一切正常,您现在可以删除标签:git tag -d temp

这与所做的事情几乎相同git rebase -i --rebase-merges=no-rebase-cousins,但如果您是 git 新手,那么出现混乱或错误的可能性要低得多。

最后一点:如果您要编辑的提交是合并提交,并且此后没有其他合并提交,那么您还有另一种选择可以解决合并提交变基的问题。不要对要编辑的提交进行变基,而只对之后的提交进行变基,但在待办事项列表的最开始处(各行之前pick <hash> message)插入一个中断。这样,您可以git commit --amend在变基开始重新应用提交之前编辑合并提交。然后,当它重新应用提交时,它将在新修改的合并之上执行此操作。