Linux环境SVN命令行使用经验总结

  1. 在windows机器上开发得差不多了之后,打包传送到开发机编译,在开发机上解决编译错误。

[缺点] 浪费时间在打包解包,机器间传输代码。

  1. 在windows机器上开发之后,check in代码进分支,在开发机上check out或者update后,进行编译,解决编译错误。相当于把svn作为一种机器间通信方式。

[缺点] 提交进svn的代码甚至都没有编译过,我只能说,svn不是这样用的。

  1. 在linux开发机上安装samba, 在windows环境下开发,开发机上编译。

[优点] 在windows环境编译,很便捷;可以实时在开发机上编译。

[缺点] 如果不用命令行,TortoiseSVN在samba下慢得不能忍。

  1. 完全在Linux开发机上开发,编译。

[优点] 反馈更敏捷,命令行都已经提交完代码了,乌龟svn可能还在龟速更新。

[缺点] 缺少图形界面, svn操作完全是命令行的,不太直观。

通常大多数习惯前三种模式。在windows环境使用TortoiseSVN, 各种操作都封装的很好,使用起来也很傻瓜。最近在linux环境下开发,发现svn命令行用熟了比TortoiseSVN更好用,最重要的是反应速度更快。

我们的svn工作模式
SVN并行开发管理策略
总的原则:trunk保证相对稳定。分支合并到主干时将冲突降至最低。

(1) trunk用于集成、测试、发布,可以提交fixbug代码,但不允许直接提交新特性。

(2) 特性在分支上开发,在编译、测试通过后才能合并到主干。

(3) 特性分支确定一个负责人,负责每天执行从trunk到分支的合并。合并回trunk前,先执行一次trunk到dev的合并,然后在trunk上使用复兴分支。

(4) 特性分支的存在时间不能太长,不超过一周为宜。合入主干后不能继续使用。

相册特性开发-采用特性分支

Linux环境SVN命令行使用经验总结_第1张图片
特性分支: 为了使新特性的开发不影响测试或发布,把新特性开发放在分支上进行管理,分支的生命周期取决于特性的开发周期,该策略的特点是:

1) trunk用于集成、测试、发布

2) 新特性放在分支上开发

3) 分支负责人定期(如每天)把trunk的变更同步至分支

4) 分支合并回trunk前先执行trunk到分支的合并,然后使用复兴分支

5) 分支合并回trunk后,分支生命周期结束,清理分支。

第三方代码管理-采用供应商分支

Linux环境SVN命令行使用经验总结_第2张图片
这里的供应商分支通常是指对第三方源代码的管理,供应商分支的管理通常步骤如下:

1) 创建供应商分支目录,导入供应商代码,供应商代码的维护在此分支上进行

2) 将供应商分支拷贝(branch/tag方式)到trunk或开发分支的某个目录下

3) trunk或开发分支不对供应商分支代码做修改

4) trunk或开发分支确认使用供应商分支的新版本时,把供应商分支合并到trunk或开发分支

可能会有人存在疑问,为什么要对供应商内容做管理?

供应商代码和自己的产品代码可以看着是两个产品线,供应商的代码可能随时会发生变化,为了不让供应商代码的变更影响自己产品的正常研发,就有必要使用分支独立管理供应商代码。

供应商分支还可以被另外一种方案所替代,那就是:外部引用(svn:externals)

分支合并到主干策略
如果说到svn使用最痛苦的一点,那莫过于主干合分支,或者分支合主干时爆发的各种莫名其妙的冲突狂潮,如“树冲突”,“文件冲突”,“文件丢失”等等。解决起来费时费力,还容易出错,效率很低。有没有较好的解决方法,可以让日子好过一点呢?答案是有的,需要遵循下面的方法。

冲突产生的根源
svn版本管理原理
svn生成的每个版本只记录增量修改,每个文件都有一个根源版本。

根源版本

Linux环境SVN命令行使用经验总结_第3张图片
根源版本,即祖先版本,在合并的时候是比较重要的一个概念,类似于C++中基类和派生类的关系,这里所说的根源就是一个基础版本。

如上图所示,hello.h的v1版本是v2版本的根源,而v2则是v3、v4的根源。

当进行分支合并时,SVN会沿着分支和trunk追溯共同的根源版本,然后计算其差异,如果没有共同的根源,则会报树冲突,就只能使用忽略根源的方式进行合并了。

冲突1:丢失文件及可避免的树冲突(可以避免)

当多人协作开发时,如果分支间合并缺乏时序性,就有可能导致合并时丢失文件。

举个简单例子来说:
Linux环境SVN命令行使用经验总结_第4张图片

如上图所示:

A和B两人同时在2.0-dev分支上开发,A新增一个a.cpp,并提交到SVN版本库上,产生123版本;然后B基于A提交的a.cpp做修改,提交后生成一个新版本124;

如果B此时想把自己修改的版本124merge到trunk,那么问题就来了,因为124版本的根源版本是123,只合并124过来,实际上就相当于只合并124的变更内容,而此时trunk上还没有a.cpp,这时SVN就会认为trunk上的a.cpp被删除了(因为找不到),会提示用户一个树冲突;

【由于是从2.0-dev合并到trunk, trunk是主合并方,分支是从的关系(在SVN中,trunk的东西称着mine,而分支是theirs),所以处理树冲突的时候优先用mine来解决】

当124合并到trunk时,由于找不到a.cpp,SVN会报一个树冲突,用trunk解决冲突,实际上也就是不会把a.cpp合并过来,这就会导致合并时出现丢失文件的现象。

冲突2:文本冲突(无法避免)
当A、B两人同时修改一个文件的同一行时,工具不能判断到底是选择A的修改or选择B的修改,或者是A和B的修改都要,这个事情就会报一个冲突,这种冲突也就是文本冲突。

冲突3:树冲突 (无法避免)
当A、B同时改了一个文件,A删除了该文件,而B修改了该文件,这时由于二者的修改无法进行合并,所以只能让用户二选一,要么删除该文件、要么保留该文件,这种冲突是树冲突。

树冲突产生的场景比较多,以下A和B的任何一种操作组合都会导致树冲突。

Linux环境SVN命令行使用经验总结_第5张图片
推荐的合并实践
1) 创建分支时,在日志中写明主干当前版本号。

2) 创建分支后,每天同步一次主干到分支, 并在日志中写明合入的主干当前版本号,便于定位问题。合并命令的用法见小节《常用svn命令》

每天合并问题最容易定位与解决,这也应了敏捷开发中小步快跑的思想,以及持续集成的初衷都是一样的;如果这个频率不能保证,每周也至少2-3次,否则解决冲突与定位问题的代价就大了。

3)合并回主干前,先执行一次主干到分支的合并,然后在主干上使用复兴分支。复兴分支使用了合并跟踪技术(svn1.5以上),能够不指定合并版本范围就将分支中的改动自动合入主干。

4)特性分支的存在时间不能太长,不超过一周为宜。合入主干后不能继续使用,否则当下次从trunk合到此分支时,会引入大量的树冲突。

原文http://www.5iops.com/html/2013/release_0417/266.html

你可能感兴趣的:(SVN)