我认为问题在于合并的工作方式与您想象的不同。你写
既然新的发布分支包含了所有的特性分支变更集(什么都没有被撤销),为什么默认分支也没有接收到所有这些变更集呢?
当您合并两个分支时,将其视为将所有更改从一个分支应用到另一个分支是错误的。因此default
分支不会“接收”来自release2
. 我知道这是我们通常对合并的看法,但这是不准确的。
合并两个变更集时真正发生的情况如下:
Mercurial 找到两个变更集的共同祖先。
对于两个变更集之间不同的每个文件,Mercurial使用祖先文件、第一个变更集中的文件和第二个变更集中的文件运行三向合并算法。
在您的情况下,您正在合并修订版 11 和 12。最不常见的祖先是修订版 8。这意味着 Mercurial 将从修订版开始在文件之间运行三向合并:
修订版 8:无退出
修订版 11:功能分支已退出
修订版 12:无退出
在三向合并中,变化总是胜过没有变化。Mercurial 发现文件在 8 和 11 之间发生了更改,并且在 8 和 12 之间没有看到任何更改。因此它在合并中使用修订版 11 中的更改版本。这适用于任何三向合并算法。完整的合并表如下所示,其中old
, new
, ... 是三个文件中匹配的块的内容:
ancestor local other -> merge
old old old old (nobody changed the hunk)
old old new new (they changed the hunk)
old new old new (you changed the hunk)
old new new new (hunk was cherry picked onto both branches)
old foo bar <!> (conflict, both changed hunk but differently)
由于这种令人惊讶的合并行为,我担心根本不应该退出合并变更集。如果您尝试退出合并,Mercurial 2.0 及更高版本将中止并抱怨。
一般来说,可以说三向合并算法假设所有变化都是好的。因此,如果您合并branch1
,dev
然后稍后通过回退撤消合并,则合并算法将认为状态比以前“更好”。这意味着您不能只是在稍后重新合并以恢复已撤消的更改branch1
。dev
您可以做的是在合并到default
. 您只需合并并始终保留要合并到的发布分支中的更改default
:
$ hg update default
$ hg merge release2 --tool internal:other -y
$ hg revert --all --rev release2
$ hg commit -m "Release 2 is the new default"
这将回避问题并迫使default
就像release2
. 这假设在default
没有合并到发布分支的情况下绝对不会进行任何更改。
如果您必须能够发布带有跳过功能的版本,那么“正确”的方法是根本不合并这些功能。合并是一项强有力的承诺:您告诉 Mercurial,合并变更集现在拥有来自其两个祖先的所有好东西。只要 Mercurial 不会让您在合并时选择自己的基本修订版,三向合并算法就不会让您改变主意退出。
但是,您可以做的是撤销 backout。这意味着您将功能分支中的更改重新引入发布分支。所以你从一个图表开始
release: ... o --- o --- m1 --- m2
/ /
feature-A: ... o --- o /
/
feature-B: ... o --- o --- o
您现在认为 A 功能不好,并且您取消了合并:
release: ... o --- o --- m1 --- m2 --- b1
/ /
feature-A: ... o --- o /
/
feature-B: ... o --- o --- o
然后,您将另一个功能合并到您的发布分支中:
release: ... o --- o --- m1 --- m2 --- b1 --- m3
/ / /
feature-A: ... o --- o / /
/ /
feature-B: ... o --- o --- o /
/
feature-C: ... o --- o --- o --- o --- o
如果您现在想重新引入 A 功能,那么您可以退出b1
:
release: ... o --- o --- m1 --- m2 --- b1 --- m3 --- b2
/ / /
feature-A: ... o --- o / /
/ /
feature-B: ... o --- o --- o /
/
feature-C: ... o --- o --- o --- o --- o
我们可以将增量添加到图表中,以更好地显示何时何地发生了什么变化:
+A +B -A +C --A
release: ... o --- o --- m1 --- m2 --- b1 --- m3 --- b2
在第二次退出之后,您可以再次合并feature-A
,以防在那里添加了新的变更集。您要合并的图表如下所示:
release: ... o --- o --- m1 --- m2 --- b1 --- m3 --- b2
/ / /
feature-A: ... o -- a1 - a2 / /
/ /
feature-B: ... o --- o --- o /
/
feature-C: ... o --- o --- o --- o --- o
你合并a2
和b2
。共同的祖先将是a1
。这意味着您在三向合并中需要考虑的唯一更改是a1
anda2
和a1
and之间的更改b2
。这里b2
已经有大部分的变化“在”a2
所以合并会很小。