svn分支合并的一个小心得

假设你公司部署了一套svn服务,那么整个根目录/下所有的版本提交都是共享一个递增的Revision号的,这是一个前提。

版本号

svn是基于patch实现的版本管理,怎么理解呢?就是如果你有一个/a/file.txt文件,那么你每次提交它都会保存和上一个版本之间的diff文件,目标当然就是节约空间了,举个例子:

假设一开始/a/file.txt刚创建出来,version是1,然后你提交一次version=3(为什么不是2?因为我要强调的是所有文件共享一个递增的version号,所以很有可能别人在此期间提交过其他文件),那么svn记录的是/a/file.txt 1-3.diff文件,也就是保存1和3版本之间变动了什么内容。

分支

理解了上述内容后,我们再来看分支是怎么玩的。一般拉分支,说白了就是svn copy一份/a/file.txt到/b/file.txt而已,这就是拉分支了,copy完了把/b/file.txt通过svn ci 提交上去,那么/b/file.txt也会分配一个version号,用来表示这次提交,这就算分支创建完成。

其实,svn压根不会维护什么分支关系,它只会维护一个路径的所有版本号时间轴和版本间的diff。在拉分支的时候,最重要的其实是记住你copy的/a/file.txt当前version是多少,这又是为什么呢?

其实也不难,svn的分支合并,并不是直接比较/a/file.txt和/b/file.txt这2个文件内容的差异来实现的,这是很大的误区,这是git的原理,但不是svn的。我们继续举个例子:

假设我们在/a/file.txt的version=1的时候copy了一份到/b/file.txt,提交后/b/file.txt分配到了version=2这个版本。接着,我们修改/a/file.txt的内容并再次提交,分配得到version=3这个版本。这时,我想把/a/file.txt的变动合入到/b/file.txt,该怎么做呢?

我们知道/a/file.txt的版本在此期间从1变成了3,对应一个1-3.diff这个patch文件,而/b/file.txt是从version=1的/a/file.txt拷贝而来的,因此我们把1-3.diff这个patch文件合入进来,就会和/a/file.txt变得一模一样了。这就是svn基于patch的版本管理原理,导致我们在分支合并的时候,必须自己计算好应该合入的版本号区间,以免错过某些patch文件。

必须明确一点,svn可不会维护/b/file.txt最后合并了/a/file.txt的什么version区间,说的更直白一点,svn不管理分支间的关系,只管理单个路径的版本号历史和版本间patch!因此,每次svn merge时一定要明确的-r ver1:ver2来指定/a/file.txt的版本区间,同时在svn ci的时候-m信息中记录下本次合并了哪个分支的哪个版本号区间,比如:svn ci -m “merge /a/file.txt -r ver1:ver2″,这样下次你再合并/a/file.txt的时候,就可以以ver2作为左区间,以及/a/file.txt最后一次提交的ver4作为右区间(也可以用HEAD表示/a/file.txt的最新版本),从而再次发起svn merge。

如果你遵循这个规范,那么就算你从多个分支向自身合并,或者分支间互相合并,也不会手忙脚乱了。

svn这么麻烦,不如早点学学git吧。

发表评论

电子邮件地址不会被公开。