SVN 树冲突和目录丢失问题

来源:互联网 发布:身体域纳米网络 编辑:程序博客网 时间:2024/05/21 20:23

转载自:http://www.oschina.net/question/103087_12309


SVN 树冲突和目录丢失问题(2

前面的博文《SVN树冲突和目录丢失问题(1》,介绍了重现 update导致树冲突的重现过程。那么应该如何解决树冲突,以及如何找回丢失目录呢?首先我们需要了解:

什么是树冲突?

首先关于树冲突的概念,最好的参考是:SVN BOOK的有关树冲突的章节

·             平时我们说的冲突,是因为对同一文件的不同修改造成的冲突。

·             树冲突,指的是由于目录(文件)树的改变,造成内容修改修改不能匹配在同一对象(目录/文件)上

·             例如:由于在一个分支中修改的目录和文件,在另外的分支出现了改名的操作。

·             或者像 yzw的例子,因为两个分支同时增加了一个同名的目录,导致了树冲突。

树冲突的解决,首先要说的是要最好使用 svn 1.6的客户端。因为 svn 1.5的客户端对树冲突的处理不好,甚至根本发现不了树冲突,很容易忽略潜在的冲突,出现意想不到的结果。

SVN BOOK 中举了一个本地修改,远程重命名的例子。

例如 svn 1.5 处理这种本地修改/远程文件改名的情况,可能会出现如下结果:

·             发现远程改名,则检查本地文件是否包含修改,若不包含修改直接删除。

·             结果因为远程改名的文件,本地包含修改,因此不删除,而是保留该文件,但是文件的状态变为未受版本控制状态。

·             本地会显示一个新增文件,实际上是本地修改文件的原始(修改前)版本重命名后的文件。

·             这时,如果不太细心(谁那有那么细心?),就会丢失本地的改动。

对于 svn 1.5 最困难的是发现冲突,当然解决冲突也要靠手工比较完成:将本地文件改动在重命名后文件中再次改动一次!

对于 svn1.6 来说,引入了树冲突的概念,看似复杂度增加了,实际上是解决了两个问题:

·             识别冲突的问题:
将本地修改的文件标记为树冲突

·             改动合并的问题:
将本地修改合并到远程改名后的文件中。因为远程改名后的文件来自于本地修改的原始文件

当然对于远程重命名的例子,还要你最终的决定权还是在于你自己:

·             是否接受远程的文件重命名操作?

·             你需要手动将树冲突的状态予以解决:本地文件删除即接受远程重命名;

·             或者将远程添加的文件删除即不允许重命名。

·             对于前一种状况(即接受远程重命名),本地改动 SVN 1. 6的客户端已经自动合并到远程改名后的文件中了。

那么对于 yzw 的情况呢?

本地和远程同时添加目录?

yzw 遇到的树冲突,是因为本地和远程同时添加了相同的目录。实际上,我们在上一个博客中已经看到了两种不同的解决方案影子:

·             本地添加 somedir目录并提交后,执行合并,显示:合并引发的树冲突

o                这时,如果执行 svn resolve –accept working somedir命令解决冲突的话,

o                就相当于说:采用我增加的 somedir目录,他增加的 somedir目录不算数

o                然后提交即可

·             树冲突发生后:

o                还原冲突

o                删除主线中的目录。潜台词是:我本地的修改不要了,而是使用远程(分支)添加的目录

o                然后再执行从分支到主线的合并操作

o                合并成功,提交。

o                也就是说,采用的策略是:采用他增加的 somedir目录,我增加的 somedir目录不算数

看看实际操作的例子:

接受我的修改,远程的修改不算数

·             合并引发树冲突状态

·                    ~/tmp/svntf/trunk$ svn st

·                     M      .

·                    ?       .svn-merge-conflict

·                    ?       .svn-update-conflict

·                    ?       .svn-orignal

·                          C somedir

·                          >   本地增加,动作增加,操作合并

·             使用 svn resolve –accept working解决冲突:
~/tmp/svntf/trunk$
 svn resolve –accept working somedir
“somedir”
的冲突状态已解决
~/tmp/svntf/trunk$ svn st
M .
? .svn-merge-conflict
? .svn-update-conflict
? .svn-orignal

·             显示的目录的属性有改变,是因为增加了一个 svn:merge-info属性

·                    ~/tmp/svntf/trunk$ svn pl -v .

·                    “.” 上的属性:

·                      svn:mergeinfo

·                        /branches/0.x:2-4

·             提交合并的结果

·                    ~/tmp/svntf/trunk$ svn ci -m "忽略分支 0.x的改动,我的增加是对的。"

·                    正在发送       trunk

·                     

·                    提交后的版本为 5

·                    ~/tmp/svntf/trunk$ svn st

·                    ?       .svn-merge-conflict

·                    ?       .svn-update-conflict

·                    ?       .svn-orignal

·                    ~/tmp/svntf/trunk$ svn pl -v .

·                    “.” 上的属性:

·                      svn:mergeinfo

    /branches/0.x:2-4

接受远程的修改,我的修改不算数

上一个博文中,我几经尝试,进入到了由于更新引发的树冲突。但是在上一个博客示例最后的更新引发树冲突的状态,虽然也可以用 svn resolve命令解决树冲突,但是无法提交。

总是报错

~/tmp/svntf/trunk$ svn st

 M      .

+  C somedir

      >   本地增加,动作增加,操作更新

+    somedir/branch.txt

~/tmp/svntf/trunk$ ls somedir

branch.txt

~/tmp/svntf/trunk$ svn resolve --accept working somedir

“somedir”的冲突状态已解决

~/tmp/svntf/trunk$ svn st

 M      .

+    somedir

+    somedir/branch.txt

~/tmp/svntf/trunk$ svn ci -m "删除我的增加的目录,分支 0.x的增加是对的。"

增加          somedir

svn: 提交失败(细节如下):

svn: 目录 “/trunk/somedir”已经过时

无论你如何执行 svn update,解决过时错误,也仍然不能提交。会陷入一个无穷无尽的冲突解决==>过时冲突的循环中。

一个撤销本地修改,接受远程分支修订的解决的办法是:

1.           还原

2.                ~/tmp/svntf/trunk$ svn revert -R .

3.                已恢复“.”

4.                已恢复“somedir”

5.                ~/tmp/svntf/trunk$ svn up

6.                版本 4

7.                ~/tmp/svntf/trunk$ svn st

?       somedir

8.           找回在 .svn/entries中已经丢弃的 somedir我使用 svn up –set-depth infinity但是并不能更新出来。如果先执行 –set-depth为其他,在执行 –set-depth infinity倒是能够找回 somedir。但是这个方法太过奇怪,好像是 SVN的一个 BUG,通过奇怪的操作绕过去了一样。我用下面的命令找回丢失的 somedir目录:

9.                ~/tmp/svntf/trunk$ rm -rf somedir/

10.            ~/tmp/svntf/trunk$svn up

11.            版本 4

12.            ~/tmp/svntf/trunk$svn up somedir

13.            A    somedir

A    somedir/trunk.txt

14.        svn命令删除 somedir目录,并提交

15.            ~/tmp/svntf/trunk$svn rm somedir/

16.            D         somedir/trunk.txt

17.            D         somedir

18.             

19.            ~/tmp/svntf/trunk$svn ci -m "丢弃我的改动"

20.            删除           trunk/somedir

21.             

提交后的版本为 5

22.        然后将分支 0.x合并到主线,因为本地目录已经不在,合并不会出现冲突了

23.            ~/tmp/svntf/trunk$ svn merge file:///tmp/svnserver/branches/0.x

24.            ---正在合并 r2,经由 r5,到 “.”:

25.            A    somedir

26.            A    somedir/branch.txt

27.            ~/tmp/svntf/trunk$svn st

28.             M      .

29.            A  +    somedir

30.            A  +    somedir/branch.txt

31.            ~/tmp/svntf/trunk$svn ci -m "删除我的增加的目录,分支 0.x的增加是对的。"

32.            正在发送       trunk

33.            svn:提交失败(细节如下):

34.            svn:目录 “/trunk”已经过时

35.            ~/tmp/svntf/trunk$ svn up

36.            版本 5

37.            ~/tmp/svntf/trunk$svn ci -m "删除我的增加的目录,分支 0.x的增加是对的。"

38.            正在发送       trunk

39.            增加           trunk/somedir

40.            增加           trunk/somedir/branch.txt

41.             

42.            提交后的版本为 6

中间出现了一次过时问题,是因为目录属性修改,而目录的版本号尚未更新。这其实是 svn混杂版本号造成的,已经超出本博文的内容。

总结

好了,通过这个例子,我介绍了增加同名目录引发的树冲突的解决方案。

·             如何保留本地修改,取消远程修改

·             如何取消本地修改,保留远程修改

·             怎样的操作,会使 svn进入一个无法解决的冲突合并状态,以及如何解决

·             发现了一个 SVN本地目录丢失无法通过  svn update找回的问题,以及两种解决方法:

o                一个很古怪:分别使用不同的 –set-depth值执行多次 update,不过最终会成功

o                另外一个却需要知道丢失的目录名称,如果不知道本地有哪个目录缺失,就很难操作了

老杨是我见过的最牛的程序员,但是他的 CVS的死忠和对 SVN 的憎恨让我觉得异常诧异。可能他和Linus Torvalds很想像,但又有不同,因为 Linus CVS SVN 同样憎恨。

我估计老杨一旦有时间,一旦掌握了 Git,他就会把 CVS(还有SVN?)扔到九霄云外。不过我估计他还得需要 SVN GIT 接合使用,因为毕竟他现在做的是商业软件开发,还需要精细的代码授权(至少是对别人授权)。


1 0
原创粉丝点击