Subversion 1.6.0和目录树冲突

Filed Under (General, Subversion Client) by rocksun on 31-03-2009

Tagged Under : ,

大多数Subversion用户熟悉文本的冲突,一个经典场景是你在工作拷贝修改了一个文件,而svn update从版本库带来的变更也包含了这个文件的修改,而这两部分变更无法干净的结合为一个本地变更,结果就是文本冲突。Subversion 1.6.0将此概念扩展倒了目录级别,例如,你在本地删除了一个文件,而更新会带来这个文件的文本变更时的情况,这种新的冲突被叫做目录树冲突。

让我们看一个预期中目录树冲突的简单例子,不过首先看一下在Subversion 1.5.6的老“方式”。

和文本冲突一样,目录树冲突会在更新、转移或合并(从技术上讲,检出时也会)时发生,在这个例子中,我们从trunk合并到trunk的一个分支上。

1.5.6

 在我们的工作拷贝,我们有一个有文本修改的文件:

1.5.6> svn st
M notes\obliterate\obliterate-functional-spec.txt

检查一下从trunk需要合并那些内容,我们得到了r36680:

1.5.6> svn mergeinfo --show-revs eligible %URL%/trunk .
r36680

查看r36680的日志,我们看到Barry恰好将我们本地修改的文件改名:

1.5.6> svn log -v -r36680 %URL%
------------------------------------------------------------------------
r36680 | Barry | 2009-03-19 11:21:25 -0400 (Thu, 19 Mar 2009) | 1 line
Changed paths:
A /trunk/notes/obliterate/obliterate-func-spec.txt (from
/trunk/notes/obliterate/obliterate-functional-spec.txt:36679)
D /trunk/notes/obliterate/obliterate-functional-spec.txt
Just making a file name a bit shorter
------------------------------------------------------------------------

想到Subversion将重命名作为复制和删除的组合执行,当我们合并r36680时,重命名的添加部分会成功,但是删除部分则由于删除本地的修改而不能成功,Subversion通常会通知不能删除未版本化的修改:

 

1.5.6> svn merge %URL%/trunk . -c36680
--- Merging r36680 into '.':
A notes\obliterate\obliterate-func-spec.txt
Skipped 'notes\obliterate\obliterate-functional-spec.txt'

当合并之后,留下了两个版本化的spec文件,Barry重命名的一部分以及我们的本地修改。我们可以以此提交,但是这不是我们希望的。在这个情况下获得正确的结果,也就是在改名的文件中包含我们的修改,因为Subversion使用复制和删除对待改名的情况,实现这个目标需要多出许多环节。

首先,我们需要使用OS的复制命令复制修改的文件到新位置:

1.5.6> copy notes\obliterate\obliterate-functional-spec.txt notes\obliterate\obliterate-func-spec.txt
Overwrite notes\obliterate\obliterate-func-spec.txt? (Yes/No/All): y
 1 file(s) copied.

然后使用Subversion来恢复到 我们最初本地修改的文件:

1.5.6> svn revert notes\obliterate\obliterate-functional-spec.txt
Reverted 'notes\obliterate\obliterate-functional-spec.txt'

现在允许我们删除它:

作为选择,你可以只使用–force选项删除和组合最初的两步。诚然,这是一个坏习惯,这样会清除掉所有的本地修改。回想我们说Subversion会努力保留未版本化的本地修改,svn delete –force就是与revert子命令不同的一个例子,所以要小心。

1.5.6> svn del notes\obliterate\obliterate-functional-spec.txt
D notes\obliterate\obliterate-functional-spec.txt

留下我们希望得到的东西,注意’notes\obliterate\obliterate-func-spec.txt’包含了我们最初的本地修改。

1.5.6> svn st
 M .
D notes\obliterate\obliterate-functional-spec.txt
A + notes\obliterate\obliterate-func-spec.txt

现在,在上面的例子中,很明显发生了什么。但是如果我们合并了几百个修订和几百个改变的路径?很容易错过这种“Skipped”的信息,提交合并。这些错误会在很久以后才能被发现。

1.6.0

现在,让我们看一下1.6.0中的目录树冲突,给定同样的分支工作拷贝:

1.6.0> svn st
M notes\obliterate\obliterate-functional-spec.txt

我们执行相同的合并,注意最显著的改变,我们看到目录树冲突,而不是跳过:

1.6.0> svn merge %URL%/trunk . -c36680
--- Merging r36680 into '.':
A notes\obliterate\obliterate-func-spec.txt
C notes\obliterate\obliterate-functional-spec.txt
Summary of conflicts:
 Tree conflicts: 1

检查工作拷贝的状态,我们看到与1.5.6的第二项区别。重命名的额外部分会和以前一样,但是会在’notes\obliterate\obliterate-functional-spec.txt’ (第7列的‘C’)报告目录树冲突。此外,有一些目录树冲突的本性,特别是合并时包含本地的修改和来自的删除。

 

1.6.0> svn st
 M .
M C notes\obliterate\obliterate-functional-spec.txt
A + notes\obliterate\obliterate-func-spec.txt

让我们假定无视目录树冲突,直接提交。这是第三个变化,Subversion不会允许包含目录树冲突的工作拷贝提交:

1.6.0> svn ci -m "I don't care what happened! Commit away" .
svn: Commit failed (details follow):
svn: Aborting commit: 'C:\SVN\1.6.0.WC\my_branch_WC\notes\obliterate\obliterate-functional-spec.txt' remains in conflict

为了提交这个合并,我们需要说出我们的决定。如果因为一些原因我们希望保留两个文件,我们可以直接解决冲突并提交变更。也有可能我们希望将变更应用到新文件,在这时我们可以解决这个冲突:

1.6.0> svn resolve --accept working -R .
Resolved conflicted state of 'notes\obliterate\obliterate-functional-spec.txt'
1.6.0> svn st
 M .
M notes\obliterate\obliterate-functional-spec.txt
A + notes\obliterate\obliterate-func-spec.txt

下面的步骤和1.5.6时一样。

注意:在1.6.0,–accept选项的svn resolve子命令对于目录树冲突没有特殊处理。只要有目录树冲突,结果相同,就像你使用废弃的svn resolved命令。只有以前的文本冲突在对–accept选项有效。

应该注意到目录树冲突的概念并不新鲜。你可以在Subversion 1.6之前的任何版本遇到目录树冲突,1.5.6的例子是一个“目录树冲突”,只是它并没有有用的方式处理。 1.6.0的目录树冲突特性主要关于识别出目录树冲突,并在没有解决时将其保持在工作拷贝。

对于每个新特性,以后的发布都会有许多要做的事情。在这里,让命令行程序更简单的解决目录树冲突就非常重要。如果你是Collabnet Desktop的用户,你很幸运。在桌面版的1.8版本,预计在2009年3月,会包含目录树冲突解决特性。这个特性会完成冲突解决的许多脏活。前面的例子中,可以轻松的将修改从 ’obliterate-functional-spec.txt’ 合并到’obliterate-func-spec.txt’,只需要一个对话框。如果你对1.6的目录树冲突感兴趣,而没有使用Collabnet Desktop,可能是一个尝试的好机会。

  

Paul Burba is a developer in CollabNet’s Version Control team. In that role he works on OSS Subversion where he is a full-committer. When not in front of his computer he’s probably on a bike somewhere.

1.6的版本库更省空间

Filed Under (Subversion Server) by rocksun on 19-02-2009

Tagged Under : ,

在Subversion1.5中的FSFS版本库中,会将修订版本文件分配到不同的目录里,默认是1000个文件一个目录。在Subversion 1.6中,更进一步,现在支持将多个修订文件打包成一个文件,从而提高访问效率并更节省空间。

最新的Subversion 1.6的程序,提供了svnadmin pack命令,可以完成这个打包的工作。经过B Smith-Mannschott的实验,一个有31100个修订的1.5版本库开始占据1.4G的空间。

经过Subversion1.6的svnadmin upgrade; svnadmin pack操作之后,经过打包,变成了1.3G。

进一步,使用1.6的svnadmin dump; svnadmin load; svnadmin pack操作之后,变成了1.1G,显著的减少了空间的占用。

关于这部分的内容可以看:http://svn.collab.net/repos/svn/branches/1.6.x/www/svn_1.6_releasenotes.html#filesystem-improvements