根据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 == RIGHT
和BASE != 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,而且我没有看到任何解释如何决定的文档。
我想知道这回答一个更复杂的问题:
答案 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到主干)时,它会看到两件事:
哪个有道理。我确信SVN只是查看每个合并文件的svn:mergeinfo
属性,并看到已经合并了一堆修订。当然,它使用它来缩小修订列表。结果只会合并未合并的修订版本。这组修订与上次从A到B(同步)以及从B到A(重新整合)合并以来的所有更改相同。
注意: 在我的实验中,我只对整个虚拟目录进行了合并。如果我只合并特定文件,我相信它会逐个文件。