Subversion没有将更改合并到重命名的文件中?

时间:2008-10-09 14:12:48

标签: svn

我使用subversion有以下问题:

我目前正在处理项目的主干,并计划进行一些重构(包括重命名文件或将文件移动到不同的目录)。

与此同时,其他人正在分支机构上开展同一项目。

有时我想将分支上所做的更改合并回主干。这包括对已在主干上重命名的文件(在分支上)所做的更改。

我做了一些测试,似乎颠覆不能跟随这些变化,或者我错过了某些(这是我希望的)。我使用以下脚本测试了这个(应该在bash中工作,假设svn存储库位于“http://myserver/svn/sandbox”):

svn co http://myserver/svn/sandbox

cd sandbox/

mkdir -p MyProject/trunk MyProject/branches MyProject/tags

cat - <<EOF >MyProject/trunk/FileOne.txt
Test
1
2
EOF

svn add MyProject

svn commit -m "init"

# create a branch
svn copy http://myserver/svn/sandbox/MyProject/trunk http://myserver/svn/sandbox/MyProject/branches/Branch_1 svn copy http://myserver/svn/sandbox/MyProject/trunk http://myserver/svn/sandbox/MyProject/branches/Branch_1

# rename the file
svn move MyProject/trunk/FileOne.txt MyProject/trunk/FileTwo.txt

svn commit -m "renamed file"

svn update 

# change the content of FileOne in branch

cat - <<EOF >MyProject/branches/Branch_1/FileOne.txt
Test
2
3
EOF

svn commit -m "changed branch"

# I now try to merge the changes in FileOne back to FileTwo
cd MyProject/trunk/
svn merge -r1:HEAD http://myserver/svn/sandbox/MyProject/branches/Branch_1
# but this yields the following message:
# Skipped missing target: 'FileOne.txt'

非常感谢任何帮助。

编辑: 也许mikegrb建议的过程可以通过首先从trunk上的svn log命令生成重命名文件(old-&gt; new)的映射来实现自动化:

svn log -v
------------------------------------------------------------------------
r33 | sme | 2008-10-09 15:17:54 +0200 (Do, 09 Okt 2008) | 1 line
Changed paths:
   D /MyProject/trunk/FileOne.txt
   A /MyProject/trunk/FileTwo.txt (from /MyProject/trunk/FileOne.txt:31)


resulting map: {FileOne.txt => FileTwo.txt}

现在使用此映射更改分支上生成的补丁文件中的文件名。

原件:

Index: FileOne.txt
===================================================================
--- FileOne.txt (.../trunk)     (revision 31)
+++ FileOne.txt (.../branches/Branch_1) (revision 34)
@@ -1,3 +1,3 @@
 Test
-1
 2
+3

改性:

Index: FileTwo.txt
===================================================================
--- FileTwo.txt (.../trunk)     (revision 31)
+++ FileTwo.txt (.../branches/Branch_1) (revision 34)
@@ -1,3 +1,3 @@
 Test
-1
 2
+3

只是一个想法,尚未完成。

4 个答案:

答案 0 :(得分:23)

我认为这是一个现有的颠覆bug - 但是不要屏住呼吸,它自2002年开始营业。

答案 1 :(得分:12)

不幸的是,这是颠覆的局限之一。当我们最近有一个类似的情况来处理我们的解决方案是为分支创建一个巨大的差异,然后通过文件手动修补主干文件。已重命名但未找到的文件将导致修补程序提示要修补文件名。非常次优。注意不会在diff中显示的二进制文件。这是促使我们评估其他版本控制系统并最终决定转换为git的重要因素之一。

答案 2 :(得分:1)

您可能需要在分支中重命名它们。你能合并从主干到分支重命名的修订吗?这可能会节省一些时间。否则,您必须在分支中重命名它们。然后尝试合并回主干。

答案 3 :(得分:1)

解决方法是在将主干与分支同步之前将分支与主干同步。

区别在于trunk到branch有一个文件要应用更改(move),而branch to trunk没有要应用更改(修改)的文件。这只是因为SVN似乎无法跟踪文件的移动/重命名位置。我不知道为什么没有,希望有充分的理由。

示例:

  • rev 1:/trunk/foo.txt已移至/trunk/folder/foo.txt
  • rev 2:/branches/mybranch/foo.txt已修改

如何将foo.txt更改合并到trunk?

解决方案:

  1. 合并从trunk到mybranch的所有修订并提交。这将导致foo.txt移动。
  2. 合并mybranch到trunk的所有修订版。这将更新foo.txt的内容,因为它们现在具有相同的路径。
  3. 注意:如果您已在主干和mybranch上移动/重命名了不同的文件,那么您就可以骑车了。我猜你必须有选择地合并更改,以便你先在两个方向上移动/重命名,然后合并更改。