有没有一种简单的方法可以在交互式变基中在提交之前添加前缀?

3
假设我有一个基于主分支的分支,它以合并提交结束:
--A---C<master]---D---E---F<my-feature]
   \ / 
    B

使用交互式 rebase 在 DE 之间添加提交 X 很简单 - 我运行以下命令:
git rebase -i master,将提交 D 的操作设置为 edit,然后重新排列提交。重排后,我在此刻创建新的提交,然后继续 rebase。现在分支看起来像这样:
...C<master]---D---X---E'---F'<my_freature]
现在,我想在CD 之间添加一个提交。
想要的结果是这样的:
C<master]---X---D'---E'---F'<my_freature]
我尝试使用以下命令:
git rebase -i master~,想要将合并提交C 设置为edit。但是交互式 rebase 忽略了合并提交 C,只提供了链 A--B--D--E,所以无法保留合并提交 C
有没有一种简单的方式,可以像这样使用交互式 rebase 在分支上添加提交呢?请注意,我可以考虑一个稍微复杂一点的解决方案,比如在 master 上创建新分支 tmp ,将提交 X 提交到它上面,然后将 my-feature 重新基于 tmp 进行 rebase,但我只是好奇是否有一种简单而直接的方法可以使用交互式rebase实现。

这是一个有趣的工作流程。我一开始不会想到在rebase操作中添加新的提交。我不知道你问题的答案,但我的方法是在F之后创建提交X,然后交互式地将其rebase在C和D之间或D和E之间,具体取决于需要的位置。 - joanis
就此而言,变基对合并不友好:让我感到沮丧的是,如果您不重新定位A^..F到另一个分支,就会失去历史记录中存在合并的事实。在过去,当我想要这样做时,我曾经使用过挑选和手动重做合并的方法。 - joanis
好的,我应该先读一下手册... git rebase -h 告诉我 --preserve-merges-p 选项尝试重新创建合并而不是忽略它们。也许这也能解决你的问题? - joanis
是的,-p 是解决方案。你在第一条评论中提出的建议非常不方便,当你将一个提交移动到一个正在改变的代码库时,你会遇到更多更糟糕或“奇怪”的合并冲突,而如果你直接检出旧的主分支,在其上插入一个新的提交,然后继续交互式地重置它,就不会有这样的问题。 - amik
做补丁时,最好选择最终位置来进行操作,这样可以更简单地减少冲突,特别是当你的分支有很多个提交记录时。 - joanis
1个回答

1
我刚刚成功地重现了您的情境,并通过在`git rebase`命令中添加`-p`选项(即`--preserve-merges`)在C和D之间插入了提交X:
git rebase -i -p master^

余下的工作流程与您所描述的一样:告诉rebase编辑合并提交,手动插入新的提交并以git rebase --continue结束。

顺便说一句,这是一个很棒的工作流程!我想我会用它。

编辑:我已经在Git 2.4上测试了这个解决方案。如果您使用的是更新版本的Git,则@torek建议使用更安全的--rebase-merges选项而不是--preserve-merges。请参见下面的注释以获取说明。


1
有一个关于使用-i--preserve-merges(或-p)的一般性建议,那就是:不要使用。:-) 新的--rebase-merges模式可以正确处理这个问题,但-p(滥用)交互式机制来进行隐含合并和重新排列pick命令序列可能会导致交互式代码执行错误的合并操作。显然,如果它对您特定的测试用例有效,则该测试用例没有触发该问题,但如果您使用--rebase-merges,则会获得带有标签的交互式会话,并且标签将构建新的拓扑结构,因此您可以确保在所有情况下都能正常工作。 - torek
@torek 谢谢你的信息。我的 Git 版本可能太旧了,我没有看到 --rebase-merges 选项。对于 OP 的问题,交互式变基用于插入提交,而不使用重新排序。如果我正确理解了您的评论,这意味着我的解决方案对于这个特定的用例应该是安全的。我将编辑我的答案建议在更近版本的 Git 中使用 --rebase-merges - joanis
谢谢,这正是我所寻找的。我认为在这种情况下,“-p”选项是安全的,因为我实际上并没有触及合并提交或之前的任何内容,我只需要一种交互式变基的替代方法,能够在检出基础提交后立即停止。 - amik

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