svn树冲突:我做错了什么?
每当我尝试在SVN中合并时,我都会遇到成堆的树冲突。在这个示例脚本中,只有一个,但仍然是svn树冲突:我做错了什么?,svn,merge,tree-conflict,Svn,Merge,Tree Conflict,每当我尝试在SVN中合并时,我都会遇到成堆的树冲突。在这个示例脚本中,只有一个,但仍然是 #!/bin/bash svnadmin create repo svn checkout file://`pwd`/repo wc cd wc mkdir trunk branches svn add trunk branches svn commit -m 'created trunk and branches' echo red > trunk/colors svn add trunk/colo
#!/bin/bash
svnadmin create repo
svn checkout file://`pwd`/repo wc
cd wc
mkdir trunk branches
svn add trunk branches
svn commit -m 'created trunk and branches'
echo red > trunk/colors
svn add trunk/colors
svn commit trunk -m 'created trunk/colors with red inside'
svn copy trunk branches/a
svn commit branches/a -m 'created branches/a'
echo green >> trunk/colors
svn commit trunk -m 'added green to trunk/colors'
echo blue >> branches/a/colors
svn commit branches/a -m 'added blue to branches/a/colors'
svn update
svn merge ^/trunk branches/a
我的结果是:
Checked out revision 0.
A trunk
A branches
Adding branches
Adding trunk
Committed revision 1.
A trunk/colors
Adding trunk/colors
Transmitting file data .
Committed revision 2.
A branches/a
Adding branches/a
Adding branches/a/colors
Committed revision 3.
Sending trunk/colors
Transmitting file data .
Committed revision 4.
Sending branches/a/colors
Transmitting file data .
Committed revision 5.
Updating '.':
At revision 5.
--- Merging r2 through r5 into 'branches/a':
C branches/a/colors
--- Recording mergeinfo for merge of r2 through r5 into 'branches/a':
U branches/a
Summary of conflicts:
Tree conflicts: 1
我知道SVN并不以合并友好而闻名,但我不得不假设,在这种情况下,不知何故,这是我的错。感谢您的指点。问题似乎在于使用本地
svn副本而不是远程副本
-svn copy trunk branches/a
-svn commit branches/a -m 'created branches/a'
+svn copy ^/trunk ^/branches/a -m 'server side copy from trunk to branches/a'
+svn update
虽然说本地拷贝“不推荐使用这种技术”,但并没有将此列为理由。相反,它只是讨论廉价的服务器端拷贝、磁盘使用情况、时间等。您演示的案例应该会产生正常的冲突,而不应该导致树冲突
我怀疑您的用例正在执行子树合并(请注意svn merge命令中的子树路径)。
所有mergeinfo内容只存储在您的签出的顶层
来自“svn帮助合并”:
SOURCE specifies the branch from where the changes will be pulled, and
TARGET_WCPATH specifies a working copy of the target branch to which
the changes will be applied. Normally SOURCE and TARGET_WCPATH should
each correspond to the root of a branch. (If you want to merge only a
subtree, then the subtree path must be included in both SOURCE and
TARGET_WCPATH; this is discouraged, to avoid subtree mergeinfo.)
下面的代码片段显示了我相信您在避免子树合并的同时正在寻找的功能。
它使用“svn开关”来避免子树合并和多个WC
export SVN_REPO=~/svntest
cd $SVN_REPO
rm -rf $SVN_REPO/*
svnadmin create repo
svn mkdir file:///$SVN_REPO/repo/trunk -m "created trunk"
svn mkdir file:///$SVN_REPO/repo/branches -m "created branches"
#
svn checkout file:///$SVN_REPO/repo/trunk wc
cd wc
echo red > colors
svn add colors
svn commit . -m 'created trunk/colors with red inside'
#
svn cp file:///$SVN_REPO/repo/trunk file:///$SVN_REPO/repo/branches/a -m 'created branches/a'
#
echo green >> colors
svn commit . -m 'added green to trunk/colors'
#
svn switch file:///$SVN_REPO/repo/branches/a .
echo blue >> colors
svn commit -m 'added blue to branches/a/colors'
svn update
svn merge file:///$SVN_REPO/repo/trunk
结果:
Committed revision 1.
SVN_REPO/repo/branches -m "created branches"
Committed revision 2.
SVN_REPO/repo/trunk wc
Checked out revision 2.
cd wc
echo red > colors
svn add colors
A colors
svn commit . -m 'created trunk/colors with red inside'
Adding colors
Transmitting file data .
Committed revision 3.
SVN_REPO/repo/branches/a -m 'created branches/a'
Committed revision 4.
echo green >> colors
svn commit . -m 'added green to trunk/colors'
Sending colors
Transmitting file data .
Committed revision 5.
SVN_REPO/repo/branches/a .
U colors
Updated to revision 5.
echo blue >> colors
svn commit -m 'added blue to branches/a/colors'
Sending colors
Transmitting file data .
Committed revision 6.
svn update
Updating '.':
At revision 6.
Conflict discovered in '/home/jbellamy/svntest/wc/colors'.
Select: (p) postpone, (df) diff-full, (e) edit,
(mc) mine-conflict, (tc) theirs-conflict,
(s) show all options: p
--- Merging r4 through r6 into '.':
C colors
--- Recording mergeinfo for merge of r4 through r6 into '.':
U .
Summary of conflicts:
Text conflicts: 1
svn diff
Index: .
===================================================================
--- . (revision 6)
+++ . (working copy)
Property changes on: .
___________________________________________________________________
Added: svn:mergeinfo
Merged /trunk:r4-6
Index: colors
===================================================================
--- colors (revision 6)
+++ colors (working copy)
@@ -1,2 +1,6 @@
red
+<<<<<<< .working
blue
+=======
+green
+>>>>>>> .merge-right.r6
已提交修订版1。
SVN_回购/回购/分行-m“已创建分行”
承诺修订2。
SVN_回购/回购/中继wc
已签出修订版2。
cd-wc
回声红>颜色
添加颜色
A颜色
svn提交-m“已创建行李箱/内部带有红色的颜色”
添加颜色
传输文件数据。
承诺修订3。
SVN_回购/回购/分支机构/a-m“已创建分支机构/a”
承诺修订4。
回声绿色>>颜色
svn提交-m“将绿色添加到行李箱/颜色”
发送颜色
传输文件数据。
承诺修订5。
SVN_回购/回购/分行/a。
U色
更新至第5版。
回声蓝色>>颜色
svn提交-m“将蓝色添加到分支/a/颜色”
发送颜色
传输文件数据。
承诺修订6。
svn更新
正在更新“”:
第6次修订。
在“/home/jbellamy/svntest/wc/colors”中发现冲突。
选择:(p)推迟,(df)差异完全,(e)编辑,
(mc)地雷冲突,(tc)他们的冲突,
(s) 显示所有选项:p
---正在将r4到r6合并到“.”
C颜色
---正在录制将r4到r6合并到“”的合并信息:
U
冲突摘要:
文本冲突:1
svn差异
索引:。
===================================================================
--- . (第6次修订)
+++ . (工作副本)
对的属性更改:。
___________________________________________________________________
新增:svn:mergeinfo
合并/中继:r4-6
索引:颜色
===================================================================
---颜色(第6版)
+++颜色(工作副本)
@@ -1,2 +1,6 @@
红色
+>.merge-right.r6
您遇到的问题不是由于“本地副本”[1]本身造成的。问题在于,在修订3中,您复制了一个混合修订工作副本()
如果我们一直运行您的脚本,直到您将“trunk”复制到“branchs/a”,我们会发现存在一个混合版本的工作副本:
>svn st -v
0 0 ? .
1 1 pburba branches
1 1 pburba trunk
2 2 pburba trunk\colors
因此,当您将“trunk”复制到“branchs/a”时,实际上是在复制trunk@1和树干/colors@2:
>svn copy trunk branches\a
A branches\a
>svn st -v
0 0 ? .
1 1 pburba branches
A + - 1 pburba branches\a
A + - 2 pburba branches\a\colors
1 1 pburba trunk
2 2 pburba trunk\colors
>svn ci -m "Copy mixed-rev trunk"
Adding branches\a
Adding branches\a\colors
Committed revision 3.
在查看r3的详细日志时,我们可以最清楚地看到这一点:
>svn log -v -r3
------------------------------------------------------------------------
r3 | pburba | 2013-03-11 15:31:23 -0400 (Mon, 11 Mar 2013) | 1 line
Changed paths:
A /branches/a (from /trunk:1)
A /branches/a/colors (from /trunk/colors:2)
Copy mixed-rev trunk
------------------------------------------------------------------------
跳转到有问题的合并,我们有一个“干净”的工作副本,没有混合修订和本地修改。到目前为止一切顺利:
>svn st -v
5 5 pburba .
5 5 pburba branches
5 5 pburba branches\a
5 5 pburba branches\a\colors
5 4 pburba trunk
5 4 pburba trunk\colors
但是,如果我们使用svn mergeinfo命令预览将合并的修订,我们会注意到第2版符合条件:
>svn mergeinfo --show-revs eligible ^/trunk branches\a
r2
r4
但是等等,revison 2是“颜色”的添加
>svn log -v -r2
------------------------------------------------------------------------
r2 | pburba | 2013-03-11 15:43:52 -0400 (Mon, 11 Mar 2013) | 1 line
Changed paths:
A /trunk/colors
created trunk/colors with red inside
------------------------------------------------------------------------
我们在修订版3中创建分支时已经复制了它!那么,为什么Subversion再次尝试合并它呢?原因又回到了我们制作的WC-to-WC副本的混合版本。合并目标“分支/a”知道它是从trunk@1,在添加“躯干/颜色”之前。因此,合并认为修订版2尚未合并到分支/a,并尝试合并此更改,将“颜色”添加到已存在同名文件的“a”中,从而导致树冲突:
>svn merge ^/trunk branches\a
--- Merging r2 through r5 into 'branches\a':
C branches\a\colors
--- Recording mergeinfo for merge of r2 through r5 into 'branches\a':
U branches\a
Summary of conflicts:
Tree conflicts: 1
>svn st
M branches\a
C branches\a\colors
> local file obstruction, incoming file add upon merge
Summary of conflicts:
Tree conflicts: 1
因此,我们用混合版本WC-to-WC-copy欺骗了Subversion,这在复制过程中有效地将版本2带到了分支。那么为什么Subversion不能检测到这一点并跳过修订版2呢?在本例中,我们可以这样做,但如果修订2包括对“主干”的其他更改,该怎么办?e、 g:
>svn log -v -r2
------------------------------------------------------------------------
r2 | pburba | 2013-03-11 15:43:52 -0400 (Mon, 11 Mar 2013) | 1 line
Changed paths:
A /trunk/colors
A /trunk/README
M /trunk
created trunk/colors with red inside, add a README file, and set the
svn:ignore property on trunk
------------------------------------------------------------------------
Subversion不支持将修订的一部分合并到给定路径,它要么全部合并,要么什么都不合并
~~~~~
那么如何避免这个问题呢?正如您已经发现的,进行URL到URL的复制可以解决这个问题。为什么?因为当复制源是URL时,根据定义,它处于某种统一版本:
>svn log -v -r3
------------------------------------------------------------------------
r3 | pburba | 2013-03-11 16:02:59 -0400 (Mon, 11 Mar 2013) | 1 line
Changed paths:
A /branches/a (from /trunk:2)
Create branch 'a' from 'trunk' with a URL-to-URL copy.
------------------------------------------------------------------------
但是,您也可以使用指向WC副本的URL来完成相同的任务:
svn commit trunk -m 'created trunk/colors with red inside'
-svn copy trunk branches/a
+svn copy ^/trunk branches/a
svn commit branches/a -m 'created branches/a'
或者只需在原始脚本中的WC到WC副本之前更新WC:
svn commit trunk -m 'created trunk/colors with red inside'
+svn update
svn copy trunk branches/a
svn commit branches/a -m 'created branches/a'
您的原始解决方案,URL到URL的副本,然后是更新,是IMO的最佳选择。更新&WC到WC的副本和URL到WC的副本都允许在提交副本之前对副本进行其他更改——最好创建分支的修订版除了副本之外没有其他更改。也就是说,所有这些选项都可以正常工作[2]
[1] 在Subversion中,我们通常将其称为工作副本到工作副本,简称WC到WC副本。将其与URL到URL、URL到WC或WC到URL副本进行对比。WC到URL副本也容易出现上述问题。另请参见“svn复制--帮助”
[2] 当然,即使使用这三个选项之一仍然会导致文本冲突,但这是意料之中的,因为在创建分支后,我们对主干和分支上的“颜色”文件进行了不兼容的更改
>svn merge ^/trunk branches\a
--- Merging r3 through r5 into 'branches\a':
C branches\a\colors
--- Recording mergeinfo for merge of r3 through r5 into 'branches\a':
U branches\a
Summary of conflicts:
Text conflicts: 1
Conflict discovered in file 'branches\a\colors'.
Select: (p) postpone, (df) diff-full, (e) edit, (m) merge,
(mc) mine-conflict, (tc) theirs-conflict, (s) show all options: p
>svn st
M branches\a
C branches\a\colors
? branches\a\colors.merge-left.r2
? branches\a\colors.merge-right.r5
? branches\a\colors.working
Summary of conflicts:
Text conflicts: 1
您的svn cp
命令使用两个遥控器。当我更新脚本,将remotes用于copy命令时,它也起到了作用。另外,我的脚本输出特别显示了存储到分支/a