在Mercurial中使用移植物的后果

时间:2012-03-07 09:24:09

标签: version-control mercurial branch dvcs cherry-pick

最近在Mercurial中维护发布分支时,最近有几个关于跳过更改的问题。例如:

自从它在2.0中引入以来,我一直想知道如何使用graft来避免这个问题。给出这样的修订树:

A---B---C---D---E---F---G---H---I---J

假设我们需要创建一个跳过Evil更改E的发布分支。

hg update -r D
hg graft "F::J"

给我们:

A---B---C---D---E---F---G---H---I---J
             \
              --F'--G'--H'--I'--J'
  • Q1:刚刚发生了什么事?我可以理解transplant会从F::J生成补丁,然后将它们应用到D,但据说graft使用3向合并而不是补丁。那么......这是怎么回事?为什么会更好?

让我说我现在修复E,并将其合并到我的发布分支中。

                  --E2-----------------
                 /                     \
A---B---C---D---E---F---G---H---I---J---M1
             \                            \
              --F'--G'--H'--I'--J'---------M2--

M1是直接合并;没什么特别的。 M2正在合并具有“相同”(或至少等同)变化的分支。

  • Q2:这次合并只是使用DJ'M1进行的正常三向合并吗?
  • 问题3:mercurial存储/使用有关移植手术的额外信息以帮助合并吗?

最后......

  • 问题4:像这样的流程存在哪些潜在问题?

2 个答案:

答案 0 :(得分:119)

当您更新到D并移植F::J时,Mercurial会运行多个合并。它将从这个合并开始:

M = three_way_merge(local=D, other=F, base=E)

如果我们为状态+dC之间的差异写D,那么我们从:

开始
        +d     +e     +f
---- C ---- D ---- E ---- F ----

顺时针旋转图形90度,上面的三向合并如下所示:

    -e  
  .---- D
 /
E
 \
  '---- F
    +f

也就是说,我们假设我们从E开始,并应用-e的反面来转到D。我认为是+e的反向补丁。从E开始,我们还使用正常的delta F进入状态+f。这里没什么奇怪的 - 我们已经在存储库中拥有所有状态(DEF)。如此看来,很明显我们可以合并DF

合并是“完成钻石”的问题。因此,我们发现了一个新的状态M,它是DF的混合,其中DM之间的差异类似于{{1} +fF之间的差异与M相似。它看起来像这样:

-e

-e +f' .---- D ----. / \ E M \ / '---- F ----' +f -e' delta变为+f+f' delta变为-e。这只是一个正常的三向合并,但效果很有意思:我们已将-e'应用于F而不是D

合并后,EM的第二个父级将被删除:

F

重申:我们已将 -e +f' .---- D ----. / \ E M \ '---- F +f 的“效果”复制到F,也就是说,我们找到了应用于D的delta(+f')与D应用+f时的效果相同。我们可以稍微理清图表来获得:

E

结果是 +f' --- D ---- M \ '---- E ---- F +e +f 使用完整的三向机制嫁接到F

  • Q1:这里发生了什么?那么......这是怎么回事?为什么会更好?

    A1:使用合并比补丁更好,因为合并机器会考虑重命名等事项。

  • Q2:此合并是使用D,J'和M1进行的正常3向合并吗?

    A2:是的,嫁接不会改变图表的拓扑结构。

  • 问题3: mercurial存储/使用了有关移植操作的额外信息以帮助合并吗?

    A3:否。

  • 问题4:这样的流程有哪些潜在问题?

    A4:从合并的角度来看,它应该可以正常工作。它会复制一些可能让人感到困惑的历史。

答案 1 :(得分:6)

Q1:有冲突时会有所帮助。您可以使用常用的合并工具(对我而言,它是内联冲突标记,我使用Emacs的smerge模式编辑)。

Q2:这是正常的合并。

问题3:否。

第四季:我认为拥有两个几乎相同的分支是很难的。