我有一个典型的情况:我将一个dev
分支合并到master
中,然后意识到我犯了一个错误并恢复了合并。然后将修订添加到dev
中,并希望再次合并。当然,我不能直接合并它,因为从git的角度来看,它已经被合并了。
还原还原提交,应用您的修复程序。继续前进。
优点:简单。
缺点:历史被宠坏了。很难指责比这次还原还深。
我想从头开始重建dev
分支,然后再次合并。根据书中所述,应使用git rebase --force-rebase
轻松完成。但是分支的历史记录并不是那么简单,它包含许多合并,包括来自master
的合并。我要尊重这些。
让我们举个例子:
master|
v
-*------------X-----Y---------*-----*----M-W
\ / \ \ / /
\ / \ -*- /
\ / -D- G--H-- /
\ / / \ / \ /
------A--B--C-----E--F--------I-----J
^
|dev
错误的合并是M
。其还原为W
。我认为在dev
到B
上的提交都是可以的,因为B
已作为master
合并到X
中。我想以完全相同的拓扑重建从B
开始的分支。请参阅下面的树。新提交标记有撇号。您可以看到如何将提交C..J
重构为C'..J'
。相应地,dev
被重设为dev'
。其他提交未更改。在这里,我仅在重新设置基础之前部分描绘了dev
,以免在图纸上造成太多麻烦。它隐藏在省略号...
后面。
...-F-G-... master|
/ v
-*------------X-----Y---------*-----*-----M-W
\ / \ \ / /
\ / \ -*- /
\ / -D' G'-H'- ...-J <-dev
\ / / \ / \
------A--B--C'----E'-F'-------I'----J'
\ ^
C-... |dev'
然后,我将应用修订K
并将此新分支合并到master
:
...-F-G-... master|
/ v
-*------------X-----Y---------*-----*-----M-W------M2
\ / \ \ / / /
\ / \ -*- / /
\ / -D' G'-H'- ...-J <-dev /
\ / / \ / \ /
------A--B--C'----E'-F'-------I'----J'--------K
\ ^
C-... |dev'
优点:良好的历史记录。
缺点:我不知道该怎么做。
好吧,似乎rebase
对此有一个选择,它被称为--rebase-merges
。但这并不能满足我的要求。它将所有作为dev
的祖先和B
的后代的提交作为基准。其中包括提交X
和Y
。 master
上已经有哪些,我为什么要它们? (实际上,它还带来了更古老的历史中的其他一些贡献,我还不知道为什么,但这不是重点)。
相反,我想带的是dev
而不是master
的祖先的提交(当然,在错误合并之前考虑master
)。对我来说听起来真的很容易。但是我不知道该怎么做,只能通过手工构造这种不同的提交,并以某种方式手工挑选它们,并小心翼翼地保护父母。
那么,如何重建分支,只包含在分支上完成的工作并尊重合并提交?
PS 我们不能简单地将master
重设为M^
,这太容易了。
答案 0 :(得分:0)
基于https://github.com/git/git/blob/master/Documentation/howto/revert-a-faulty-merge.txt,我会
git checkout dev
$EDITOR files
git commit files -m 'Fix'
git checkout master
git revert W
git merge dev
当您重新合并时,保留还原更改是必要的。
答案 1 :(得分:0)
好吧,好像我找到了解决方法:
git rebase --interactive --rebase-merges B dev
这恰好产生了我想要的历史记录。归功于@mstrap作为提示。
我不确定为什么它能按我想要的方式工作。