在Mercurial中使用嫁接的后果


98

最近在维护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'
  • 问题1:这里发生了什么?我可以理解,这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:这是合并只是使用普通的3路合并DJ'以及M1
  • 问题3:Mercurial是否存储/使用了有关嫁接操作的额外信息以帮助合并?

最后...

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

Answers:


119

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

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

如果我们写出+d状态C和之间的差值D,那么我们将从以下内容开始:

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

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

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

也就是说,我们假装我们开始E和应用的对面-eD。我认为是的反向补丁+e。从开始,E我们还进入F了正常三角洲状态+f。没有什么奇怪的在这里-我们拥有所有的状态(DE,和F)资源库中已。这样看来,很明显我们可以合并DF

合并是“完成钻石”的问题。因此,我们找到新的状态M即是一个组合D,并F和其中从差DM类似于+f从差FM类似-e。看起来像这样:

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

+f三角洲成为+f'-e三角洲成了-e'。这仅仅是一个正常的三方合并,但效果很有趣:已应用FD替代的E

合并后,Mto 的第二个父对象F被删除:

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

要重申:我们已经复制的“效果” FD,也就是,我们已经找到了增量(+f'),其适用于D当得到同样的效应+f应用于E。我们可以稍微拉直图表以获得:

       +f'
--- D ---- M
     \
      '---- E ---- F
        +e     +f

结果是使用完整的三向机械将其F嫁接到D了该设备上。

  • 问题1:这里发生了什么?所以.......这是怎么工作的?为什么会更好?

    解答1:使用合并比使用补丁程序要好,因为合并机制考虑了重命名之类的事情。

  • 问题2:此合并是否只是使用D,J'和M1的常规三向合并?

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

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

    A3:没有

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

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


4
好问题,好答案:)。两者都+1!
劳伦斯·霍尔斯特

谢谢马丁。无论谁提出来,这都是一些相当时髦的想法。我有主意,但需要解决一般情况。我猜想不管您要移植到的节点之间的路径是什么,还是从那里移植出来的节点之间都没有关系?
Paul S

3
@PaulS:我想您需要知道的是,嫁接可以比移植更强大的方式复制变更集。从某种意义上说,这种方法很坚固,可以处理重命名,并且可以解决合并工具中的冲突。细节处处都是奇怪的合并,但是对于日常使用嫁接来说,希望这不是必需的!:-)
马丁·盖斯勒

3
不,但是我很想了解我不需要的东西;-)无论如何,我通过一个更通用的示例作为您的示例。
Paul S

@PaulS如果是这样,那么我几乎不敢向您提及此事……但是您可以查阅Darcs及其补丁理论。上面关于将图形旋转90度的技巧使我想起了很多他们在合并时如何谈论通勤补丁的方法。毛茸茸的东西:-)
马丁·盖斯勒

6

问题1:有冲突时有帮助。然后,您可以使用常用的合并工具(对我来说,这是嵌入式冲突标记,我使用Emacs的smerge-mode编辑)。

问题2:这是正常合并。

Q3:没有

问题4:我认为拥有两个几乎完全相同的分支是很丑陋的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.