尝试撤消时的冲突更改Subversion中的示例

时间:2012-06-25 18:52:17

标签: svn merge

在探索Subversion中的功能时,我尝试测试svnbook的分支和合并章节的基本合并部分的撤消更改子部分中描述的用例。我使用的是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.

存储库中的修订号与文件中的行匹配,以便在/trunk/testcode.py@rN中,文件的最后一行是以rN结尾的行。我想要做的是删除以r4结尾的行,保持之前和之后的所有其他内容不变。

按照svnbook的Undoing Changes部分中的示例,我运行命令

svn merge -c -4 file:///path_to_repos/trunk

这会产生冲突(在运行该命令时,而不是在提交时),其中merge-left文件包含直到第r4行的所有内容,而merge-right文件包含直到第r3行的所有内容。换句话说,该命令似乎想要将整个文件还原为版本3或4,而不是删除过去的更改,从而删除后续修订中的更改(在本例中为5和6)。

我在svnbook中读取示例的方式,其中用户反转在修订版303中提交的更改并将结果提交到修订版350而没有冲突,我运行的命令应该生成svn状态为M的文件保留除了以r4结尾的那一行之外的所有行。

我是否错误地阅读了本书的示例,示例是错误的,还是存在其他形式的用户错误,我陷入了不知情的境地?

1 个答案:

答案 0 :(得分:4)

基本问题是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)

尝试将提交还原到文件的开头或结尾(示例中的修订版本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

你应该在这里遇到冲突,原因相同:

...                    <-- 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)

请注意,这仅仅是为了概念性地解释为什么文件的开头和结尾看起来有所区别,而不是作为理解Subversion合并过程的全面解释。