Git rebase 跳过相同的提交

Bre*_*min 3 git

根据git rebase 文档

如果上游分支已经包含您所做的更改(例如,因为您邮寄了一个应用到上游的补丁),那么该提交将被跳过。例如,在以下历史记录上运行 git rebase master (其中 A' 和 A 引入了相同的更改集,但具有不同的提交者信息):

      A---B---C topic
     /
D---E---A'---F master 
Run Code Online (Sandbox Code Playgroud)

将导致:

               B'---C' topic
              /
D---E---A'---F master
Run Code Online (Sandbox Code Playgroud)

我无法理解的是这种优化的需要是什么?如果 git 会像这样重新定位:

               A''---- B'---C' topic
              /
D---E---A'---F master
Run Code Online (Sandbox Code Playgroud)

哪里出了问题?(A = A' = A'')

编辑:为了让自己更清楚,让我们说F恢复A'. 现在变基将不适用A的补丁上F,只是B'C'。在这种情况下, git rebase 行为可能会出乎意料,对我来说这没有意义。

tor*_*rek 5

可能有存储相同的源代码树相继提交。这就是你在这里会得到的,因为A''不会引入任何更改——这些F更改已经 F; 从DIFFEF包括由于从DIFF同样的变化EA'

换句话说,快照中的快照A''将与 中的快照相同F。Git 将这种提交对称为空提交:也就是说,如果父提交与子提交匹配,并且子提交不是合并提交,则 Git 表示子提交为“空”(即使它仍然具有完整快照) . 该git commit命令需要标志--allow-empty来进行这样的提交。

此外,中的提交消息A''可能与 中的提交消息相同A'。如果是这样,A''在所有有用的方面都是多余的。消除它可能是最好的行动方案。

请注意,git rebase最初是使用 实现的git format-patch,它将每个提交转换为与其父项的差异,1带有附加文本以使补丁可通过电子邮件发送。一个单独的程序,git am读取“邮箱格式”文件(电子邮件消息的序列)并应用补丁,使用附加文本来重现提交作者、作者日期和日志消息。但是,格式化补丁并git am拒绝使用空补丁。因此,使用这两个程序来实现提交复制的 rebase 的初始版本不得不删除这些“空”提交。

Moderngit rebase有额外的后端,而不仅仅是git am. 这些可以创建或复制空提交。您必须提供-k标志以git rebase获取 rebase 以故意创建此类提交,并且该-k标志强制 rebase 使用交互式或合并后端,而不是git am后端(当然也修改其初始设置以告诉它不要删除“空”自动提交)。

您还可以使用单独的git cherry-pick命令或使用音序器进行大量樱桃采摘来手动进行变基。与 rebase 一样,cherry-pick 默认拒绝复制“空”提交,要求--allow-empty和/或--keep-redundant-commits标志保留此类提交。


1git format-patch根本无法格式化合并提交,因为它们有多个父级。

  • 我自己没有做出这个决定,但我发现它在实践中效果很好。不过,对于那些它“不能”很好地发挥作用的特殊情况,了解这一点是个好主意。始终检查变基的结果是否仍然良好,例如,通过自动化测试。如果失败,请记住您可以使用“ORIG_HEAD”或引用日志将其回滚,然后手动正确地重做。 (2认同)
  • [对此对话的早期看法](/sf/ask/3145631961/)。 (2认同)