如何在git rebase期间展平合并提交

时间:2017-10-03 11:14:53

标签: git

我有一个主题分支,看起来如下

stacked = False

我要在另一位家长上进行交互式变换这个分支。如何在变基过程中平息分歧的历史?我想摆脱合并提交,并使历史变为线性(仍然包含那些分歧提交,但不包括合并提交本身,因为它没有引入任何更改)

1 个答案:

答案 0 :(得分:1)

嗯,我不推荐这种方法......事实上,99%的时间我不认为对“更简单”历史的渴望是合理的......但如果你想这样做,那就是几乎是rebase的默认行为。

如果你刚开始使用rebase,就像在

中一样
git rebase --interactive --onto <new-parent> 2955a39^ 77a706b

你应该发现所有的非合并提交都在TODO列表中,而合并提交本身就消失了。默认情况下,我认为rebase将遵循合并的父母的顺序;我不确定,但无论如何,如果需要,你可以重新排序TODO列表。

请注意,我在此假设需要--onto,因为您提到您正在将提交移至新父级。这是否真的有必要取决于新父母与旧父母的关系。让我们看一下更大的图片来看看差异:

  P
 /
o -- X -- o -- o -- O <--(master)
      \
       A -- B --- M -- D <--(branch)
             \   /
               C

如果您只是将branchX移至O,那么您实际上并不需要--onto;您可以将master视为您的上游,因为旧的分支点是新父级的祖先。

git rebase -i master branch

但是,如果你将分支移动到任意父母(我推断 - 也许是错误的 - 从问题的措辞),那么这是行不通的。例如,要将branch移至P需要--onto语法,因为如果您仅使用P作为上游,那么X会陷入rebase。 (这是一个足够简单的示例,您可以在待办事项列表编辑器中修复它;但一般来说,记住upstreamnewparent之间的差异非常重要。)

这不仅是默认行为,而且覆盖它(通过提供--preserve-merges选项)特别是建议用于交互式rebase。

那我为什么不推荐呢?有几个原因。

最重要的一点:如果合并应用了任何更改,它们将会丢失。通常,合并不应应用更改,但有一些问题。显然,如果存在合并冲突,它们的解决方案都在合并提交中。 (这与我不推荐这个的第二个原因相关,但我已经超越了自己......)如果合并是使用默认策略以外的策略完成的,那么这将被视为合并中的变化丢失。并且“应该”放在一边,有可能有人因为没有特别好的理由而创造了一个邪恶的合并。如果你知道这些都不适用,那就好了......

但接下来的原因是你可能不得不做大量的冲突解决,因为“分支”提交会在“主线”提交中逐一重播。分支上的提交越多,问题就越大。

(在极端情况下:我经常听到的一个抱怨是,“在一次改变期间,我不得不一遍又一遍地解决同样的冲突。”老实说,我不确切地知道这是怎么发生的,我从来没有过它的一个例子来全面检查自己(可能部分原因是因为我没有因审美目的而改变),但是有足够的人说它碰巧我必须相信它们。)

最后,rebase创建的新提交未经测试。这似乎并不重要,因为它们只是“中间提交”,但它确实打破了依赖于bisect的调试工作流程。

相关问题