SVN 树冲突和目录丢失问题(2)
前面的博文《SVN 树冲突和目录丢失问题(1)》,介绍了重现 update 导致树冲突的重现过程。那么应该如何解决树冲突,以及如何找回丢失目录呢?首先我们需要了解:
后记: 睡醒一觉后,发现俺的闺女小雪已经学会了 one, two, three, four!真的不是吹的,2岁5个月的小孩,千字文已经可以从“天地玄黄背”到“如松之胜”,上个月开始莫名的喜欢英文歌,今天早晨居然会说 one, two, three, four! “姑娘,别累坏了,不过要是你喜欢,...” 欣喜之余,想到给 yzw 的博文莫不如扩充到 one, two, three, four。于是就有了下面两个博文:
什么是树冲突?
首先关于树冲突的概念,最好的参考是:SVN BOOK的有关树冲突的章节。- 平时我们说的冲突,是因为对同一文件的不同修改造成的冲突。
- 树冲突,指的是由于目录(文件)树的改变,造成内容修改修改不能匹配在同一对象(目录/文件)上
- 例如:由于在一个分支中修改的目录和文件,在另外的分支出现了改名的操作。
- 或者像 yzw 的例子,因为两个分支同时增加了一个同名的目录,导致了树冲突。
- 发现远程改名,则检查本地文件是否包含修改,若不包含修改直接删除。
- 结果因为远程改名的文件,本地包含修改,因此不删除,而是保留该文件,但是文件的状态变为未受版本控制状态。
- 本地会显示一个新增文件,实际上是本地修改文件的原始(修改前)版本重命名后的文件。
- 这时,如果不太细心(谁那有那么细心?),就会丢失本地的改动。
- 识别冲突的问题: 将本地修改的文件标记为树冲突
- 改动合并的问题: 将本地修改合并到远程改名后的文件中。因为远程改名后的文件来自于本地修改的原始文件
- 是否接受远程的文件重命名操作?
- 你需要手动将树冲突的状态予以解决:本地文件删除即接受远程重命名;
- 或者将远程添加的文件删除即不允许重命名。
- 对于前一种状况(即接受远程重命名),本地改动 SVN 1. 6的客户端已经自动合并到远程改名后的文件中了。
本地和远程同时添加目录?
yzw 遇到的树冲突,是因为本地和远程同时添加了相同的目录。实际上,我们在上一个博客中已经看到了两种不同的解决方案影子:- 本地添加 somedir 目录并提交后,执行合并,显示:“合并引发的树冲突”
- 这时,如果执行 svn resolve --accept working somedir 命令解决冲突的话,
- 就相当于说:“采用我增加的 somedir 目录,他增加的 somedir 目录不算数”
- 然后提交即可
- 树冲突发生后:
- 还原冲突
- 删除主线中的目录。潜台词是:我本地的修改不要了,而是使用远程(分支)添加的目录
- 然后再执行从分支到主线的合并操作
- 合并成功,提交。
- 也就是说,采用的策略是:“采用他增加的 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 . A + C somedir > 本地 增加,动作 增加,操作 更新 A + 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 . A + somedir A + somedir/branch.txt ~/tmp/svntf/trunk$ svn ci -m "删除我的增加的目录,分支 0.x 的增加是对的。" 增加 somedir svn: 提交失败(细节如下): svn: 目录 “/trunk/somedir” 已经过时无论你如何执行 svn update,解决过时错误,也仍然不能提交。会陷入一个无穷无尽的冲突解决==>过时冲突的循环中。 一个撤销本地修改,接受远程分支修订的解决的办法是:
- 还原
~/tmp/svntf/trunk$ svn revert -R . 已恢复“.” 已恢复“somedir” ~/tmp/svntf/trunk$ svn up 版本 4。 ~/tmp/svntf/trunk$ svn st ? somedir
- 找回在 .svn/entries 中已经丢弃的 somedir我使用 svn up --set-depth infinity 但是并不能更新出来。如果先执行 --set-depth 为其他,在执行 --set-depth infinity 倒是能够找回 somedir。但是这个方法太过奇怪,好像是 SVN 的一个 BUG,通过奇怪的操作绕过去了一样。我用下面的命令找回丢失的 somedir 目录:
~/tmp/svntf/trunk$ rm -rf somedir/ ~/tmp/svntf/trunk$ svn up 版本 4。 ~/tmp/svntf/trunk$ svn up somedir A somedir A somedir/trunk.txt
- 用 svn 命令删除 somedir目录,并提交
~/tmp/svntf/trunk$ svn rm somedir/ D somedir/trunk.txt D somedir ~/tmp/svntf/trunk$ svn ci -m "丢弃我的改动" 删除 trunk/somedir 提交后的版本为 5。
- 然后将分支 0.x 合并到主线,因为本地目录已经不在,合并不会出现冲突了
~/tmp/svntf/trunk$ svn merge file:///tmp/svnserver/branches/0.x --- 正在合并 r2,经由 r5,到 “.”: A somedir A somedir/branch.txt ~/tmp/svntf/trunk$ svn st M . A + somedir A + somedir/branch.txt ~/tmp/svntf/trunk$ svn ci -m "删除我的增加的目录,分支 0.x 的增加是对的。" 正在发送 trunk svn: 提交失败(细节如下): svn: 目录 “/trunk” 已经过时 ~/tmp/svntf/trunk$ svn up 版本 5。 ~/tmp/svntf/trunk$ svn ci -m "删除我的增加的目录,分支 0.x 的增加是对的。" 正在发送 trunk 增加 trunk/somedir 增加 trunk/somedir/branch.txt 提交后的版本为 6。
中间出现了一次过时问题,是因为目录属性修改,而目录的版本号尚未更新。这其实是 svn 混杂版本号造成的,已经超出本博文的内容。
总结
好了,通过这个例子,我介绍了增加同名目录引发的树冲突的解决方案。- 如何保留本地修改,取消远程修改
- 如何取消本地修改,保留远程修改
- 怎样的操作,会使 svn 进入一个无法解决的冲突合并状态,以及如何解决
- 发现了一个 SVN 本地目录丢失无法通过 svn update 找回的问题,以及两种解决方法:
- 一个很古怪:分别使用不同的 --set-depth 值执行多次 update,不过最终会成功
- 另外一个却需要知道丢失的目录名称,如果不知道本地有哪个目录缺失,就很难操作了
后记: 睡醒一觉后,发现俺的闺女小雪已经学会了 one, two, three, four!真的不是吹的,2岁5个月的小孩,千字文已经可以从“天地玄黄背”到“如松之胜”,上个月开始莫名的喜欢英文歌,今天早晨居然会说 one, two, three, four! “姑娘,别累坏了,不过要是你喜欢,...” 欣喜之余,想到给 yzw 的博文莫不如扩充到 one, two, three, four。于是就有了下面两个博文:
- 《SVN 树冲突和目录丢失问题(3)》 一个更加简单重现 yzw 问题的方法
- 《SVN 树冲突和目录丢失问题(4)》 一个更有意义和技术含量的冲突解决办法,可以让合并的双方不是“你死我活”的争斗,而是“谐和”