从其他答案的 cmets 来看,您似乎只想使用 IDE 命令来执行此操作。这很可能意味着没有解决方案。 IDE 集成通常提供最常见的操作;你想要做的不是一个普通的操作,因为(正如蒂姆在他的回答中所暗示的那样)摆脱这种情况的最好方法就是不要参与其中。
不同解决方案之间的主要区别在于您希望最终提交图的外观。假设你从
O -- o -- X -- X -- B1 -- B2 -- B3 <--(branch1)
\
X -- X -- A <--(branch2)
其他人建议的cherry-pick 解决方案对于这种情况来说还不错。虽然可能没有 IDE 支持,但它相对简单。它留给你
O -- o -- X -- X -- B1 -- B2 -- B3 <--(branch1)
\
X -- X -- A -- B1' -- B2' -- B3' <--(branch2)
现在这些分支之间的merge 可能会在重复的补丁上绊倒,但您指出这些不是您无论如何都将完全合并的分支。 (这引发了一个不同的问题,关于“共享存储库的分支”是否是存储这两个东西的最明智的方式,因为它们不是同一事物的替代版本。我假设你这样做是为了促进共享共同点代码,但是有专门为解决该问题而设计的工具,如果您使用它们,很明显如何将错误修复共享到公共代码。错误我离题了,现在我们可以回到处理您今天遇到的情况。 ..)
另一种让您知道这些是“两个地方的相同更改”的替代方法是将错误修复从branch1 重新定位,然后将其合并到branch1 和branch2。这涉及重写 branch1 历史记录,因此如果您已经共享 branch1(即已将 Bn 提交推送到共享存储库),这对您来说可能不是一个好选择。但是如果你这样做,它看起来像
git checkout branch1
git branch common
git reset --hard HEAD~3
git rebase --onto `git merge-base branch1 branch2` branch1 common
git checkout branch1
git merge common
git checkout branch2
git merge common
请注意,我假设错误修复提交位于分支的末尾;如果不是,这个过程会有点困难(重置和后续的变基将被交互式变基取代)。即使它们是,reset 命令的确切参数取决于正在移动的提交数量。这会给你
X -------- x ------- M1 <--(branch1)
/ /
O -- o -- B1' -- B2' -- B3' <--(common)
\ \
X ----- X ---- A ---- M2 <--(branch2)
优点是您现在拥有common 分支,这是对共享代码进行进一步更改的地方(然后再次合并到branch1 和branch2)。
但同样,如果错误修复提交已经被推送到branch1 上的远程,那么 branch1 现在必须“强制推送”,这为共享偏僻的;因此,如果您不确定它是否适合您的情况,请参阅 git rebase 文档以获取有关该情况的信息。
还有其他选项,但这些选项涵盖了您可能希望提交图如何结束的最明智的选项。