如何在没有死亡的情况下扭转合并对极化分支的影响?
这个问题困扰了我好几个月,我终于放弃了.
您有1个存储库,有2个 命名分支.A和B.
A发生的变化将不可避免地发生在B.
B上直接发生的变化绝不会发生在A上.
在这样的配置中,将"B"合并为"A"会在存储库中产生可怕的问题,因为对B的所有更改都出现在A中,就好像它们是在A中制作的一样.
从这种情况中恢复的唯一"正常"方式似乎是"退出"合并,即:
hg up -r A hg backout -r BadMergeRev --parent BadMergerevBeforeOnA
这看起来很好,花花公子,直到你决定稍后在正确的方向合并,你最终会发生各种令人讨厌的事情,特别是分支B上删除/注释掉的代码突然变得没有注意或没有注释.
到目前为止,还没有一个可行的解决方案,除了"让它做它的事情,然后解决所有的问题",说实话有点fubar.
这是澄清问题的图像:
[原始图像丢失]
文件C&E(或更改C&E)必须仅出现在分支b上,而不是出现在分支a上.这里的版本A9(分支a,revno 9)是问题的开始.
修订版A10和A11是"退出合并"和"合并退出"阶段.
并且修订版B12是多变的,错误地反复删除了意图不被删除的更改.
这种困境引起了很多挫折和蓝烟,我想结束它.
尝试禁止反向合并可能是一个明显的答案,无论是使用钩子还是使用策略,我发现这种情况相当高并且发生这种情况的可能性很大,即使采取了对策,你仍然必须假设它不可避免地会发生,以便你可以解决它.
在模型中我使用了Seperate文件.这些使问题听起来很简单.这些只是代表任意变化,可能是一个单独的路线.
此外,为了增加对伤害的侮辱,在分支A上发生了实质性的变化,留下了常见的问题"分支A的变化与分支B的变化发生冲突,分支B刚刚出现(并且退出)看起来像一个变化在分支A而不是"
所有这些追溯活动解决方案的问题如下:
我们有9000次提交.
因此新鲜克隆需要半小时
如果某个存储库中甚至存在一个坏的克隆,那么它就有可能与原始存储库重新联系,并再次将其重新打开.
每个人都已经克隆了这个存储库,现在已经过了几天,正在进行提交.
一个这样的克隆,碰巧是一个真实的网站,所以"擦掉那个,从头开始"="大nono"
(我承认,上面的许多内容都有些愚蠢,但它们超出了我的控制范围).
唯一可行的解决方案是假设人们能够并且将会做错事,并且有一种方法可以"消除"这种错误.
我想我找到了一个永久修复坏合并的解决方案,并且不需要你手动检查任何差异.诀窍是返回历史记录并生成与错误合并并行的提交.
因此,我们在每个维护版本的单个产品中都有独立分支的存储库.与问题中提出的情况一样,在早期版本的分支上进行的所有更改(即该版本中的错误修正)都必须最终合并到更高版本的分支中.
具体来说,如果在BRANCH_V8上签入了某些内容,则必须将其合并到BRANCH_V9.
现在其中一个开发人员犯了以下错误:他将所有更改从BRANCH_V9合并到BRANCH_V8(即合并方向错误).此外,在糟糕的合并之后,他在注意到他的错误之前执行了一些额外的提交.
所以情况如下图所示.
o BRANCH_V8 - 13 - important commit right after the bad merge | o BRANCH_V8 - 12 - wrong merge from BRANCH_V9 |\ | o BRANCH_V8 - 11 - adding comment on BRANCH_V8 (ie. last known good state) | | o | BRANCH_V9 - 10 - last commit on BRANCH_V9 | |
我们可以解决这个错误如下:
将您的本地目录更新为BRANCH_V8的上一个良好状态: hg update 11
创建一个最后一个良好状态的新孩子:
更改一些文件$EDITOR some/file.txt
(这是必要的,因为Mercurial不允许空提交)
提交这些更改hg commit -m "generating commit on BRANCH_V8 to rectify wrong merge from BRANCH_V9"
现在的情况如下:
o BRANCH_V8 - 14 - generating commit on BRANCH_V8 to rectify wrong merge from BRANCH_V9 | | o BRANCH_V8 - 13 - important commit right after the bad merge | | | o BRANCH_V8 - 12 - wrong merge from BRANCH_V9 |/| o | BRANCH_V8 - 11 - adding comment on BRANCH_V8 | | | o BRANCH_V9 - 10 - last commit on BRANCH_V9
将新生成的头部与发生错误合并的修订版合并,并在提交之前丢弃所有更改.不要简单地合并两个头,因为你将失去合并后发生的重要提交!
合并:( hg merge 12
忽略任何冲突)
抛弃所有变化: hg revert -a --no-backup -r 14
提交更改:hg commit -m "throwing away wrong merge from BRANCH_V9"
现在看起来像是:
o BRANCH_V8 - 15 - throwing away wrong merge from BRANCH_V9 |\ | o BRANCH_V8 - 14 - generating commit on BRANCH_V8 to rectify wrong merge from BRANCH_V9 | | +---o BRANCH_V8 - 13 - important commit right after the bad merge | | o | BRANCH_V8 - 12 - wrong merge from BRANCH_V9 |\| | o BRANCH_V8 - 11 - adding comment on BRANCH_V8 | | o | BRANCH_V9 - 10 - last commit on BRANCH_V9 | |
IE浏览器.BRANCH_V8上有两个头:一个包含坏合并的修复,另一个包含BRANCH_V8上的剩余重要提交,它发生在合并之后.
在BRANCH_V8上合并两个头:
合并: hg merge
提交: hg commit -m "merged two heads used to revert from bad merge"
BRANCH_V8最终的情况现在已得到纠正,如下所示:
o BRANCH_V8 - 16 - merged two heads used to revert from bad merge |\ | o BRANCH_V8 - 15 - throwing away wrong merge from BRANCH_V9 | |\ | | o BRANCH_V8 - 14 - generating commit on BRANCH_V8 to rectify wrong merge from BRANCH_V9 | | | o | | BRANCH_V8 - 13 - important commit right after the bad merge |/ / o | BRANCH_V8 - 12 - wrong merge from BRANCH_V9 |\| | o BRANCH_V8 - 11 - adding comment on BRANCH_V8 | | o | BRANCH_V9 - 10 - last commit on BRANCH_V9 | |
现在BRANCH_V8的情况是正确的.剩下的唯一问题是从BRANCH_V8到BRANCH_V9的下一个合并将是不正确的,因为它将在错误合并的'修复'中合并,这是我们在BRANCH_V9上不需要的.这里的技巧是在不同的更改中从BRANCH_V8合并到BRANCH_V9:
首先从BRANCH_V8合并到BRANCH_V9,从坏合并之前BRANCH_V8上的正确更改.
第二次合并错误及其修复,并且无需检查任何内容,丢弃所有更改
第三,合并BRANCH_V8的其余更改.
详细地:
将您的工作目录切换到BRANCH_V9: hg update BRANCH_V9
合并BRANCH_V8的最后一个良好状态(即您生成的用于修复错误合并的提交).这种合并是像任何常规合并一样的合并,即.冲突应该像往常一样解决,不需要抛弃任何东西.
合并: hg merge 14
commit:hg commit -m "Merging in last good state of BRANCH_V8"
现在的情况是:
@ BRANCH_V9 - 17 - Merging in last good state of BRANCH_V8 |\ | | o BRANCH_V8 - 16 - merged two heads used to revert from bad merge | | |\ | +---o BRANCH_V8 - 15 - throwing away wrong merge from BRANCH_V9 | | | | | o | | BRANCH_V8 - 14 - generating commit on BRANCH_V8 to rectify wrong merge from BRANCH_V9 | | | | | | o | BRANCH_V8 - 13 - important commit right after the bad merge | | |/ +---o BRANCH_V8 - 12 - wrong merge from BRANCH_V9 | |/ | o BRANCH_V8 - 11 - adding comment on BRANCH_V8 | | o | BRANCH_V9 - 10 - last commit on BRANCH_V9 | |
在BRANCH_V8及其修复程序中合并错误合并,并丢弃所有更改:
合并: hg merge 15
还原所有更改: hg revert -a --no-backup -r 17
提交合并:hg commit -m "Merging in bad merge from BRANCH_V8 and its fix and throwing it all away"
现状:
@ BRANCH_V9 - 18 - Merging in bad merge from BRANCH_V8 and its fix and throwing it all away |\ | o BRANCH_V9 - 17 - Merging in last good state of BRANCH_V8 | |\ +-----o BRANCH_V8 - 16 - merged two heads used to revert from bad merge | | | | o---+ | BRANCH_V8 - 15 - throwing away wrong merge from BRANCH_V9 | | | | | | o | BRANCH_V8 - 14 - generating commit on BRANCH_V8 to rectify wrong merge from BRANCH_V9 | | | | +-----o BRANCH_V8 - 13 - important commit right after the bad merge | | | o---+ BRANCH_V8 - 12 - wrong merge from BRANCH_V9 |/ / | o BRANCH_V8 - 11 - adding comment on BRANCH_V8 | | o | BRANCH_V9 - 10 - last commit on BRANCH_V9 | |
合并来自BRANCH_V8的剩余更改:
合并: hg merge BRANCH_V8
提交: hg commit -m "merging changes from BRANCH_V8"
最终情况如下:
@ BRANCH_V9 - 19 - merging changes from BRANCH_V8 |\ | o BRANCH_V9 - 18 - Merging in bad merge from BRANCH_V8 and its fix and throwing it all away | |\ | | o BRANCH_V9 - 17 - Merging in last good state of BRANCH_V8 | | |\ o | | | BRANCH_V8 - 16 - merged two heads used to revert from bad merge |\| | | | o---+ BRANCH_V8 - 15 - throwing away wrong merge from BRANCH_V9 | | | | | | | o BRANCH_V8 - 14 - generating commit on BRANCH_V8 to rectify wrong merge from BRANCH_V9 | | | | o | | | BRANCH_V8 - 13 - important commit right after the bad merge |/ / / o---+ BRANCH_V8 - 12 - wrong merge from BRANCH_V9 |/ / | o BRANCH_V8 - 11 - adding comment on BRANCH_V8 | | o | BRANCH_V9 - 10 - last commit on BRANCH_V9 | |
完成所有这些步骤后,您不必手动检查任何差异,BRANCH_V8和BRANCH_V9是正确的,未来从BRANCH_V8到BRANCH_V9的合并也将是正确的.