在探索Subversion中的功能时,我试图测试svnbook的Branching and Merging章节的Basic Merging部分的Undoing Changes子部分中描述的用例.我使用的是1.6.4版本,但该部分的文本在本书的两个版本中都是相同的.
在我的工作副本目录中,我编辑一个文件testcode.py,每次编辑添加一行,并在每次编辑后提交.几次提交后,文件内容如下:
this is my first import to trunk. r1.
this is my first commit, first edit of testcode.py. r2.
this is another edit of testcode.py. r3.
this is an edit of testcode.py. i'll get rid of this one. r4.
this is another edit of testcode.py. keeping it. r5.
yet another edit. keeping it. r6.
Run Code Online (Sandbox Code Playgroud)
存储库中的修订号与文件中的行匹配,以便在/trunk/testcode.py@rN中,文件的最后一行是以rN结尾的行.我想要做的是删除以r4结尾的行,保持之前和之后的所有其他内容不变.
按照svnbook的Undoing Changes部分中的示例,我运行命令
svn merge -c -4 file:///path_to_repos/trunk
Run Code Online (Sandbox Code Playgroud)
这会产生冲突(在运行该命令时,而不是在提交时),其中merge-left文件包含直到第r4行的所有内容,而merge-right文件包含直到第r3行的所有内容.换句话说,该命令似乎想要将整个文件还原为版本3或4,而不是删除过去的更改,从而删除后续修订中的更改(在本例中为5和6).
我在svnbook中读取示例的方式,其中用户反转在修订版303中提交的更改并将结果提交到修订版350而没有冲突,我运行的命令应该生成一个svn状态为M的文件,该文件保留所有除了以r4结尾的那一行.
我是否错误地阅读了本书的示例,示例是错误的,还是存在其他形式的用户错误,我陷入了不知情的境地?
基本问题是 Subversion 的 diff 算法以一种不一定直观的方式处理文件开头和结尾的更改。您的示例满足了该极端情况,而大多数野外更改却没有。考虑在一系列提交后看起来像这样的文件:
later commit (r5)
change to be reverted at beginning of file (r2)
initial commit (r1)
change to be reverted in middle of file (r3)
initial commit (r1)
change to be reverted at end of file (r4)
later commit (r5)
Run Code Online (Sandbox Code Playgroud)
尝试将提交恢复到文件的开头或结尾(示例中的修订版 2 和 4)会产生冲突。将更改恢复到文件中间可以按预期工作。
从概念上讲,将变更集视为具有受周围行限制的范围可能会有所帮助。文件中间的更改受到周围未更改行的限制。文件开头或结尾处的更改范围会一直延伸到文件的开头或结尾,无论该点随后移动多远。
因此,在上面的示例中,修订版 5 中添加的第二行正好位于修订版 4 范围的中间。就像您期望在此处恢复修订版 10 时发生冲突一样,因为修订版 11 中的更改正好位于其中:
... <-- Line unchanged by revision 10, bounding its scope
line from revision 10 <--\
line from revision 11 | Revision 10's scope
line from revision 10 <--/
... <-- Line unchanged by revision 10, bounding its scope
Run Code Online (Sandbox Code Playgroud)
出于同样的原因,您应该预料到这里会发生冲突:
... <-- Line unchanged by revision 10, bounding its scope
line from revision 10 <--\
line from revision 11 | Revision 10's scope
<EOF> <--/ (No unchanged line bounding the scope this direction)
Run Code Online (Sandbox Code Playgroud)
请注意,这只是一个概念性解释,解释为什么文件的开头和结尾似乎被不同地对待,而不是作为理解 Subversion 合并过程的综合解释。