之前的项目已经release过若干次了,不过自己并没有参与到release的核心步骤中。TWU以学习为主要目的。因此release这块也讲的比较详细,再加上自己的的实践,算是对它有了一定的认识。
本文将从理论到实践描述如何通过创建branch的对release进行管理。
首先给release这个场景一个定义。项目开发到了一定的阶段,做了很多feature在里面,有很多bug在list中,另外还有一些需求在计划中,可能已经分析好,ready for dev了,也可能正在和客户协商中。这时候客户认为做好的feature已经暂时足够用户的使用,或者可以让真实用户进行测试。剩下的那些需求也要继续持续的做,但是不需要包含在这个release中,如果能包含其中自然更好。做新的feature有可能引入新的bug。另外已有的bug要尽量的修复。对于客户来说,他们希望在本次release中的feature尽量多,但是如前面所说,做新feature是有风险的。因此客户的目标就是在bug尽量少的情况下,尽量的多加入本次release的feature。
不开发新feature,专注于bug fix是一个选择。清理已经存在的bug,但是通常来说bug的数量可能不是特别多,因此只能有少数人工作的bug上面。剩下的开发人员就会闲置。而他们事实上是可以接着进行新feature的开发的。这又会给系统的稳定性带来不确定性。解决方案是使用版本管理软件的branch。我们在日常开发中使用的main line,通常叫做trunk。在接近release的时候,创建一个branch,作为bug fix使用。新的feature在trunk上继续进行。所有的bug fix,或者至少是非常重要,客户非常希望在本次release中修复的,要提交到branch上面。这样就能保证branch上面的bug数量持续减少,使其越来越能够成为一个稳定可供发布的版本。新feature是提交到trunk上的,这些在branch上的提交也需要被应用到trunk上,因为测试人员会在trunk上进行回归测试。回归测试是保证以前被fix的bug现在不再出现,以前没有break的功能现在依然运行良好。一般情况下回归测试实在code freeze后做的,但是如果你的功能测试写的足够好,覆盖率足够高,测试人员需要cover的点就会相对少,这样就可以减少code freeze的时间,从而保持开发的连续性。
刚才提到branch上面专注于bug fix,而且同样的bug fix也会应用到trunk上,因此trunk上面是一些混合的提交。其稳定性的趋势是不确定的。因此测试人员需要对trunk上的某些相对比较稳定的reision做标记,即打上tag,作为release候选。到deadline的时候,选择最近的一个稳定的deadline进行发布即可。假设最坏的情况是在trunk上找不到合适发布的revision,那么至少我们还有branch,branch因为只有bug fix,所以其稳定性的走向必然是提升的。可以从branch提取发布版本。
这是对于一个特定场景的一种可能的发布策略。当然实际中的release中可能千差万别,对于不同的情况,要灵活使用版本控制工具给我们提供的帮助来组织branch,trunk,merge,release。有时候也可能多于一个trunk。
下面以svn为例讲解常用的branch操作命令。
新建一个branch:
$ svn copy http://repos.com/trunk http://repos.com/branches/branch1 -m "remote copy."
默认会把源工作目录的HEAD提交一份到目标工作目录,也就是打一个branch。如果需要指定特定的版本,如1111,有以下两个办法:
$ svn copy -r1111 http://repos.com/trunk http://repos.com/branches/branch1 -m "remote copy."
$ svn copy http://repos.com/trunk@1111 http://repos.com/branches/branch1 -m "remote copy."
在有了包括trunk在内的多个分支之后,可以通过svn switch的命令在各个分支之间切换。但是鉴于这会消耗时间,还容易导致错误的产生,推荐对每个branch checkout一份代码,分别进行提交,或者做下面要提到的merge。
merge修改从一个分支到另一个分支,有三种方式:
$ svn merge sourceURL1[@N] sourceURL2[@M] [WCPATH]
$ svn merge sourceWCPATH1@N sourceWCPATH2@M [WCPATH]
$ svn merge [-c M[,N...] | -r N:M ...] SOURCE[@REV] [WCPATH]
第一种形式中,指定源URL的版本N,和目标URL的版本M,将其比较差别应用到本地工作区,这样就可以通过提交把这些修改应用到任意的分支上,当然提交到哪个分支取决于你在哪分工作拷贝中进行的提交。
第二种形式和第一种类似,不过使用的工作目录,而不是URL。
第三种是指定同一分支下的,通过-r指定两个版本号,比较两个版本号之间的差别,应用到当前工作区。或者使用-c指定一个或多个提交应用到本地。
如果是想push所有branch上的改变到trunk,使用第一种比较方便。如果是想指定连续几个提交或者是分散的几个提交应用到本地工作区,则应该选用第三种。具体的参数和语法,请参看svn文档。