SVN如何为合并选择BASE修订版?

时间:2016-09-15 05:38:39

标签: svn merge

根据redbook,从主干到分支的合并被称为“同步合并”。

Subversion如何确定 第二次 同步合并的BASE修订版?

让我解释一下。 (这很长,因为图表。非常漂亮的图片!所以忍受我,呃?)

以下是第一次同步到功能分支的方式如下:

                      .........
                     .         .
 trunk  --+---------L-----------R------
           \                     \
            \                    |
             \                   v
 feature      +------------------o-----
         r10 r11   r100         r200

(图表取自svn merge --help

在此图中,r100:200中的主干有变化。 由于这是第一次同步合并,因此BASE显然是在r10创建功能分支的点。 (行李箱上的+

在此合并之后,svn:mergeinfo更新为表示功能分支与干线合并到r200。像这样:

/trunk:1-200

svn mergeinfo ^/trunk的输出如下:

  youngest common ancestor
  |         last full merge
  |         |        tip of branch
  |         |        |         repository path

  10        200      200
  |         |        |       
-------| |------------         /trunk
   \         \               
    \         \              
     --| |------------         /branches/feature
                     |       
                     WC      

经过一些更多的开发,还会执行另一个同步合并:

                                   .........
                                  .         .
 trunk  --+----------------------L-----------R-------
           \                     \           \
            \                    |           |
             \                   v           v
 feature      +------------------o-----------x-------
         r10 r11   r100         r200        r300

这次我们将r200:300合并到功能分支中。

问题

Subversion是否选择feature @ r200作为合并的BASE,还是选择trunk @ r200作为BASE?

这很重要,因为三向差异/合并工具非常重视BASE。

如果BASE是@ r200的特征,那么在第一次同步合并之前在中继线上进行的任何更改都将成为基础的一部分。这意味着无论行李箱与它们不同,行李箱都会胜出。尽管这些变化仍应存在!

这就是问题的结束,这一行下面的内容解释了为什么我在问这个问题。

示例:

以下是第一次同步合并的方式:

BASE        LEFT           RIGHT              MERGED
trunk@r10   trunk@r200     feature@r200       sync merge result
---------   -----------    ------------       -----------------

foo         foo            foo                foo
EVIL LINE   EVIL LINE      ..deleted EVIL..   ..deleted EVIL..
bar         bar            bar                bar

正确删除了EVIL LINE

现在让我们看一下第二次同步合并:

让我们假设@ r200的特征是BASE。 EVIL LINE仍在主干中,但已从功能分支中删除:

BASE               LEFT           RIGHT              MERGED
feature@r200       trunk@r300     feature@r300       sync merge result
------------       -----------    ------------       -----------------

foo                foo            foo                foo
..deleted EVIL..   EVIL LINE      ..deleted EVIL..   EVIL LINE
bar                bar            bar                bar

为什么呢?因为3向合并工具会查看该工具并看到BASE == RIGHTBASE != LEFT,并确定正确的行动方案是采取左翼。

但是,如果我们假设trunk @ r200是BASE。没有问题,删除的行仍然被删除:

BASE        LEFT           RIGHT              MERGED
trunk@r200  trunk@r300     feature@r300       sync merge result
----------  -----------    ------------       -----------------

foo         foo            foo                foo
EVIL LINE   EVIL LINE      ..deleted EVIL..   ..deleted EVIL..
bar         bar            bar                bar

我想我的问题是我不知道如何选择BASE,而且我没有看到任何解释如何决定的文档。

我想知道这回答一个更复杂的问题:

  • 同步合并(主干进入分支),和重新整合合并(分支到主干),假设我重新正确地重新集成以便重新使用,下一次同步的BASE是什么合并和下一次重新融合?

1 个答案:

答案 0 :(得分:0)

好吧,面对没有文档,只剩下实验。

我应该提醒所有读这篇文章的人要记住这种行为将来可能会改变。

我重新创建了上面的案例,以及其他几个案例。

在所有情况下,BASE都是通过命令“svn mergeinfo”预测的。例如,这是从分支(“b0.0.1”)到trunk:

的合并
         youngest common ancestor
         |         last full merge
         |         |        tip of branch
         |         |        |         repository path

         19        21       30      
         |         |        |       
            --| |------------         branches/b0.0.1
           /        \               
          /          \              
       -------| |------------         trunk
                            |       
                            WC      

标记为“上次完全合并”的修订版用作基础。

然而:

BASE = trunk @ r21 LEFT =后备箱的WC RIGHT = trunk @ r27

当然,作为r21的BASE是有道理的。 如果想要合并未提交的更改以及主干的提示(r30),那么使用trunk的LEFT工作副本也是有意义的。

但是r27来自哪里?

这是b0.0.1最后一次与主干同步。

假设:

似乎SVN对称地处理合并的两侧。 也就是说,当将B合并到A(例如b0.0.1到主干)时,它会看到两件事:

  • 从B到A的最后一次合并(“最后一次完全合并”,例如r21)
  • 从A到B的最后一次合并(例如r27)

哪个有道理。我确信SVN只是查看每个合并文件的svn:mergeinfo属性,并看到已经合并了一堆修订。当然,它使用它来缩小修订列表。结果只会合并未合并的修订版本。这组修订与上次从A到B(同步)以及从B到A(重新整合)合并以来的所有更改相同。

注意: 在我的实验中,我只对整个虚拟目录进行了合并。如果我只合并特定文件,我相信它会逐个文件。