Subversion无法将更改合并到重命名的文件中?

25

我在使用Subversion时遇到了以下问题:

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

同时,其他人正在一个分支上开发同一项目。

在某个时间点上,我想将在分支上做出的更改合并回主干。这包括对已在主干上重命名的文件进行的更改(在分支上)。

我做了一些测试,似乎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'

非常感谢任何帮助。

编辑: 也许可以通过首先从主干上的svn日志命令生成已重命名文件的映射(旧->新)来自动化mikegrb建议的过程:

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个回答

23

我认为这是一个现有的Subversion漏洞 - 但不要抱太大希望,它自2002年以来一直存在。


2
看起来他们把这个漏洞推到了1.8版本。这只是另一种说“尚未”的方式。由于它自2002年以来就一直存在,它越来越像“永远不会”。 - deft_code
1
@deft_code 这个 bug 已经修复了吗?我现在可能正在遇到类似的问题。我使用 TortoiseSVN 的重命名功能重命名了一些文件,现在当我尝试从主干合并到我的分支(为了检查是否编译通过,然后重新集成到主干)时,它会显示“跳过缺失的目标”。 - TravisG
@TravisG - 这个错误可能已经在1.8中得到修复,这个版本可能已经于本周发布(有一个git发布,不确定其版本号)。我自己仍然使用1.7版本...你用的是哪个版本? - Chris Kimpton
1
我会很讨厌被指派去使这个变更对 SVN 兼容。/发抖 - jgitter
1
截至2016年,它仍然是开放的,尽管项目和错误跟踪器已经移动。https://issues.apache.org/jira/browse/SVN-898 - davenpcj

12

很抱歉,这是Subversion的一个限制。最近我们遇到类似情况的解决方案是为分支创建一个巨大的差异文件,然后逐个文件进行手动修补主干。重命名且未找到的文件会导致提示输入要修补的文件名。非常不优化。请注意二进制文件在diff中不会显示。这是促使我们评估其他版本控制系统并最终决定转换到Git的主要因素之一。


4
技术上讲,Git 也没有真正的重命名支持。不过它们会进行猜测,这比 SVN 做得更好。Bazaar 是唯一支持真正重命名的开源版本控制系统。 - deft_code

1

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

区别在于从主干到分支有一个文件可以应用更改(移动),而从分支到主干没有一个文件可以应用更改(修改)。这仅仅是因为SVN似乎无法跟踪文件被移动/重命名的位置。我不知道它为什么不能,希望有一个很好的理由。

例如:

  • 版本1:/trunk/foo.txt移动到/trunk/folder/foo.txt
  • 版本2:/branches/mybranch/foo.txt被修改

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

解决方案:

  1. 合并所有来自主干到mybranch的修订版本并提交。这将导致foo.txt移动。
  2. 合并所有来自mybranch到主干的修订版本。这将更新foo.txt的内容,因为它们现在具有相同的路径。

注意:如果您在主干和mybranch上移动/重命名了不同的文件,则需要进行选择性合并以便首先在两个方向上进行移动/重命名,然后合并更改。


1

很可能你需要在分支中重命名它们。你能否将从主干重命名它们的版本合并到分支中?这样可以节省一些时间。否则,你就必须在分支中重新命名它们。然后尝试将其合并回主干。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接