【问题标题】:Consequences of using graft in Mercurial在 Mercurial 中使用嫁接的后果
【发布时间】:2012-03-24 19:36:38
【问题描述】:

最近有几个关于在 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 的普通三向合并?
  • Q3:mercurial 是否存储/使用了有关移植操作的额外信息来帮助它进行合并?

最后……

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

【问题讨论】:

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


    【解决方案1】:

    Q1:当有冲突时它会有所帮助。然后,您可以使用常用的合并工具(对我来说,它是内联冲突标记,我使用 Emacs 的 smerge-mode 进行编辑)。

    Q2:这是一个正常的合并。

    Q3:没有。

    Q4:我认为有两个几乎相同的分支很难看。

    【讨论】:

      【解决方案2】:

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

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

      如果我们将+d 写成CD 状态之间的差值,那么我们可以这样开始:

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

      将图形顺时针旋转90度,上面的三路合并是这样的:

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

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

      合并是“完成钻石”的问题。所以我们找到了一个新状态M,它是DF 的混合体,其中DM 的差异类似于+f 以及FM 的差异类似于-e。它看起来像这样:

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

      +f delta 变为 +f'-e delta 变为 -e'。这只是一个普通的三路合并,但效果很有趣:我们将F 应用到D 而不是E

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

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

      重申一下:我们已经将F 的“效果”复制到D 上,也就是说,我们发现了一个增量(+f')应用于D+f 时的效果相同已应用于E。我们可以把图拉直一点得到:

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

      结果是F使用全三通机制嫁接到D上。

      • Q1:这里发生了什么?所以.......这是如何工作的?为什么更好?

        答1:使用合并比补丁更好,因为合并机制会考虑重命名之类的事情。

      • Q2:这种合并只是使用 D、J' 和 M1 的普通 3 路合并吗?

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

      • Q3: mercurial 是否存储/使用了有关移植操作的额外信息来帮助它进行合并?

        A3:没有。

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

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

      【讨论】:

      • 好问题,好答案:)。两者都 +1!
      • 谢谢马丁。无论是谁提出了这个想法,这都是一些非常时髦的想法。我有这个想法,但需要解决一般情况。我猜无论你移植到/从节点之间的路径如何,它都成立?
      • @PaulS:我认为你需要知道的是,graft 可以以比移植更强大的方式复制变更集。在处理重命名并且您可以在合并工具中解决冲突的意义上是强大的。细节在它所做的奇怪合并中,但希望这对于理解嫁接的日常使用不是必不可少的! :-)
      • 不,但我是个傻瓜,因为我试图理解我不需要的东西 ;-) 我以你的例子为基础研究了一个更一般的例子。
      • @PaulS 如果是这样,那么我几乎不敢向您提及这个...但是您可以查找Darcs 及其补丁理论。上面关于将图表旋转 90 度的技巧让我想起了他们在合并时如何谈论通勤补丁。很毛茸茸的东西:-)
      猜你喜欢
      • 1970-01-01
      • 2013-05-29
      • 2017-05-30
      • 1970-01-01
      • 1970-01-01
      • 2013-02-01
      • 2011-01-15
      • 1970-01-01
      相关资源
      最近更新 更多