基于SVN的项目管理——集中与分散

我们在此处不讨论 GIT 比 SVN 好多少,也不讨论 Maven 和 Gradle 哪个好用,基于现有的开发环境,大多数公司还是采用 SVN + Maven 来进行项目管理——因为这已经满足了大多数的代码管理需求,并且对于一个成熟的公司来讲,项目管理工具的改变可能需要很大的成本和决心,基于 GIT 的项目管理将会在以后详细介绍。

做程序开发和项目管理的老银棍们肯定知道,基于 SVN 的项目开发管理有两种方式:集中式开发和分散式开发,对应正常的语言描述来讲,集中式开发对应的是基于trunk进行开发,而分散式开发对应的就是基于branches进行开发。两者并没有绝对的好坏之分,具体采用哪种方式,完全凭个人喜好、项目架构和公司规定进行选择。

集中式开发——基于Trunk的开发

基于主干的开发方式可能是比较主流的开发方式,三个目录的主要定义如下:

trunk:开发工程(非稳定)

tag:我们认为稳定的发布包

branches:BUG、需求变更分支

用语言描述一下开发步骤:在trunk中新建一个项目,此时版本号是1.0.0-SNAPSHOT,分配权限给所有的开发人员,所有开发人员功能开发完毕之后提交代码到trunk,测试基于trunk进行测试,此时trunk处于锁定状态——不允许进行代码修改,测试完毕之后打tag,至此1.0.0-RELEASE版本正式发布,trunk中的版本号变为1.1.0-SNAPSHOT,解锁Trunk,所有开发人员开始开发1.1.0-SNAPSHOT,此时如果发生未测出来的BUG和需求变动,基于1.0.0-RELEASE的tag打分支1.0.0-PATCH,所有相关开发人员对1.0.0-PATCH进行维护开发,同时主干的1.1.0-SNAPSHOT也在同步进行。

这里很多人会问,如何将1.0.0-PATCH中的代码合并到1.1.0-SNAPSHOT中?这里用一个场景来具体描述

程序员小张负责用户注册模块的开发,在整个项目1.0.0-RELEASE发布之后,1.1.0-SNAPSHOT中小张需要对注册模块进行一个升级,此时(注意,代码没有正式开始编写),在线上运行的1.0.0-RELEASE版本发现了一个隐秘的BUG(可能是代码BUG,也可能是业务BUG),小张需要先为1.0.0-RELEASE这个tag打出一个分支1.0.0-PATCH-01对这个BUG进行修复,修复完毕之后,将1.0.0-PATCH-01合并到主干中,生成版本1.0.1-SNAPSHOT,然后发布到Tag中,此时Tags中包含1.0.0-RELEASE和1.0.1-RELEASE两个tag,之后,进行新版本1.1.0-SNAPSHOT的开发——这是最好的结果。

但是事实并非如人所愿,我们最常遇到的情况是1.1.0-SNAPSHOT已经开发了一段时间,此时发现了1.0.0-RELASE中的这个隐藏BUG,需要紧急修复,我们这里同样用一个场景来具体描述。

程序员小张负责用户注册模块的开发,在整个项目1.0.0-RELEASE发布之后,1.1.0-SNAPSHOT中小张需要对注册模块进行一个升级,此时(注意,代码已经正式开始编写),在线上运行的1.0.0-RELEASE版本发现了一个隐秘的BUG(可能是代码BUG,也可能是业务BUG),小张需要先为1.0.0-RELEASE这个tag打出一个分支1.0.0-PATCH-01对这个BUG进行修复,修复完毕之后,将1.0.0-PATCH-01单独上线,接下来的故事就比较复杂了,小张需要将1.0.0-PATCH-01中的代码手动的与正在开发的1.1.0-SNAPSHOT进行一个合并——这是常见但是异常的结果

为什么说第二个场景属于常见但是异常,这非常考验整个PMO管理——为什么会出现紧急BUG?为什么需要紧急上线?这会造成两个最直接的麻烦:

1. 线上版本不是RELEASE版本的,而是一个分支PATCH。

2. 将PATCH中的代码合并到正在开发的代码中会异常痛苦。

如果遇到这样的情况,首先不能慌张,尽可能的先将线上的BUG解决掉,再来考虑如何在新版本中合并代码的问题,这样肯定会造成1.1.0的延期发布以及1.0.1的缺失,严重的可能还需要重新审视——但是你避免不了,不过责任是比较清楚的。

当然为了能够尽可能的避免这种情况出现,一般建议新版本上线后的一段时间内(比如一个礼拜)开发人员先暂停开发做一个休整,做做项目总结、补充一些文档之类的工作,之后再进行1.1.0的迭代,这样做不仅能够完美收尾,还能减少情景2出现的概率,对公司、开发人员以及项目管理来讲都是有利的。

分散式开发——基于Branches的开发

分散式开发是基于分支branches进行开发,也是我个人比较喜欢的一种方式,其三个目录的定义如下:

trunk:稳定的主干

tag:我们认为稳定的发布包

branches:开发切片

与集中式开发不同的在于,我们branches中存在的是各个开发人员所负责的切片,而主干中则一直是稳定的SNAPSHOT版本——这其实是符合逻辑的,SNAPSHOT代表的意义是预览而不是“破烂”,至少能够正常的运行起来才能算的上是预览版,而集中式开发的主干虽然标注的是SNAPSHOT预览版,实际上其实是一个“破烂”——正常情况下你是运行不起来的,开发环境总是存在各种各样的不确定性。

用语言描述一下开发步骤:在主干trunk中新建一个项目,然后copy to branches,分别建立milestone、sp1、sp2...spN,每一个切片对应一个开发或前端或白盒测试,当大家各自开发完毕之后,提交代码,项目经理将sp1、sp2等切片合并到milestone中,这里注意了,不是合并到trunk中,而是一个分支的名字叫milestone——里程碑,专门用来合并各种代码,milestone的代码进行合并之后,部署到测试环境让测试组介入测试——完毕之后合并到trunk,然后在trunk上进行发布,在tag中归档并上线,trunk中的版本号升级到下一版本,然后所有开发切片重新切片。

上面的描述如果感到拗口的话,可以看这个场景:

项目经理建了一个项目,版本号是1.0.0-SNAPSHOT,程序员小王从项目经理那里领到一个任务是开发订单查询中心这个模块,他的切片是1.0.0-SNAPSHOT-SP1,开发完毕之后提交了代码,项目经理合并代码到milestone上,然后小王开始开发其他的代码,项目经理陆续从小张、小李那边收到SP2、SP3的代码之后,觉得可以发布一版了,叫上测试对milestone进行测试,通过之后合并到主干打tag上线,此时线上版本号是1.0.0-RELEASE,主干上的版本号是 1.1.0-SNAPSHOT,此时项目经理重新切片,所有人的代码从1.0.0-SNAPSHOT-SPn转换到1.1.0-SNAPSHOT-SPn进行开发,milestone同样变成1.1.0-SNAPSHOT,循环往复……

同样存在集中式开发的问题——老版本出现BUG怎么办?我们这里同样模拟一个场景。

1.0.0-SNAPSHOT通过了测试并且已经打tag上线了,线上版本是1.0.0-RELEASE,trunk上的版本号是1.1.0-SNAPSHOT,milestone上的版本也是1.1.0-SNAPSHOT,所有的开发都已经认领了各自的1.1.0-SNAPSHOT的SP进行下一版的开发,此时1.0.0-RELEASE发生了一个隐藏的BUG需要紧急修复并上线,项目经理找到BUG负责人小王,让他对他所负责的1.0.0-SNAPSHOT-SPn进行fix,修补完毕之后依次合并milestone、测试、打tag上线,此时线上版本是1.1.0-RELEASE,主干版本变成1.1.1-SNAPSHOT,milestone同样为1.1.1-SNAPSHOT。

到此,我们产生了一个疑问:因为小王的BUG导致主干版本比开发的SP版本高了一个版本,是不是会有冲突呢?

其实是没有冲突的,SP的版本号其实是弱化了的——实际上我根本不关心SP的版本号是否正确,当发生不正确的情况出现,由各个切片的开发人员自己通过Merge里程碑Milestone的代码解决。

总结一下分散式开发引申出来的几个概念:

SP:开发切片。

MILESTONE:里程碑,对应的是测试环境

TRUNK:主干,对应的是预发布环境

TAG:归档,对应的是线上环境

分散式开发重点解决的是保证测试环境的相对稳定、预发布环境的绝对稳定以及线上环境的绝对稳定问题,并且我们试想一下:是不是能够轻松做到持续交付了呢?

总结

集中式开发适合一些小型项目的开发,例如微服务、小组件。

分散式开发适合快速迭代——对于未知的需求贴合的更好。

时间: 2024-08-30 10:41:52

基于SVN的项目管理——集中与分散的相关文章

基于web的项目管理软件Redmine

Redmine是用Ruby开发的基于web的项目管理软件,是用ROR框架开发的一套跨平台项目管理系统,据说是源于Basecamp的ror版而来, 支持多种数据库,有不少自己独特的功能,例如提供wiki.新闻台等,还可以集成其他版本管理系统和BUG跟踪系统,例如Perforce. SVN.CVS.TD等等.这种 Web 形式的项目管理系统通过“项目(Project)”的形式把成员.任务(问题).文档.讨论以及各种形式的资源组织在一起,大家参与更新任务.文档等内容 来推动项目的进度,同时系统利用时间

在Linux上创建webrev(cont)[基于svn]

在前文中,基于git介绍了webrev工具.实际上,webrev工具还支持hg和svn.最近的工作中不可避免地要使用svn,故在此总结一下如何基于svn在Linux上创建webrev.顺便吐个槽,没有网页版的代码比对,用svn diff简直就是刀耕火种茹毛饮血啊!技术再娴熟的老司机,也架不住让你在高速公路上开拖来机Orz! 以前工作上一直用版本管理工具Mercurial (命令为hg), 个人学习的话用Git, 但从来没用过Subversion (命令为svn等) .所以,下面的先简单介绍一下如

Mac中使用svn进行项目管理

Mac中使用svn进行项目管理,借鉴了http://blog.csdn.net/q199109106q/article/details/8655204 以下方案多人亲测可用 转载请注明出处:http://blog.csdn.net/yc7369 在Windows环境中,我们一般使用TortoiseSVN来搭建svn环境.在Mac环境下,由于Mac自带了svn的服务器端和客户端功能,所以我们可以在不装任何第三方软件的前提下使用svn功能,不过还需做一下简单的配置. 我们首先来看下,如何在Mac环境

基于SpringBoot的项目管理后台

代码地址如下:http://www.demodashi.com/demo/13943.html 一.项目简介 在使用本项目之前,需要对SpringBoot,freemaker,layui,flyway等基本操作有所了解. 本项目不需要手动导入数据库表文件,项目运行起来会自动创建,只需要手动的创建对应的数据库就行了.具体操作会在下文说明. 项目实现的功能 (1) 登录 (2) 项目管理功能.该功能主要包括项目分配,项目信息的查询.删除功能,项目资料的上传.下载功能. (3) 用户管理功能.该功能主

工具——基于SVN的代码中自动生成版本号

SVN一般都是团队合作做一个项目所需用到的,为了是版本的统一, 我现在用的版本是 AnkhSvn-2.1.7141.181.msiSVN取出[SVN checkout]:从档案库中取出工作复本. 汇出[Export]:从档案库中汇出干净的工作复本,不含svn管理用数据夹. 汇入[Import]:汇入目录至档案库. SVN Commit[SVN送交]:将你所做的修改送交至档案库. SVN Update[SVN更新]:更新工作复本至目前档案库的最新版本. Update to reversion[更新

基于SVN分支开发模式流程浅析

作者:zhanhailiang 日期:2014-10-23 在使用svn多人协作开发式一般采取的工作方式如下: 检出库 创建并维护开发分支 定期将主干代码合并回分支,保证数据完整性,避免最终合并回主干时出现冲突 分支测试 将分支合并回主干 主干提交.部署 多人协作时,第三步是最经常出问题的地方,严重的甚至会导致代码被覆盖回滚情况,其原因在于分支管理者创建分支后不再或长时间从主干拉回数据,导致最终合并回主干时分支的文件甚至结构都与主干有较大差别,产生较多冲突.需要人手解决,浪费了很多时间. 针对这

基于SVN提交历史筛选作者并修改文件内容

笔者最近开发的项目中,是通过SVN做为版本管理工具的,因为需要创建的文件太多,所以有许多文件是在原有文件基础上拷贝过来修改的,这里就涉及到一个问题,原有文件中注释里填的JAVA类名.作者工号.创建时间等,都是需要修改成我自己的,因为文件太多,一个个修改起来太麻烦,所以我写了一个程序来自动扫描这些文件并替换文件中指定注释. 1.需要从项目中筛选出我创建的文件:这个就通过SVN提交日志来筛选吧,因为SVN提交历史中有提交人的工号,我通过筛选自己的工号就可以查出哪些文件是我的(当然需要注意的一点就是如

基于svn+ssh:访问svn的部署以及客户端配置

1.安装ssh sudo apt-get install ssh 2.安装subversion sudo apt-get install subversion 3.为参与项目开发的成员建立用户帐户 sudo adduser wangchengliang 4.建立名为svn的用户组 sudo addgroup svn sudo addgroup wangchengliang svn 注:这里可以根据不同的权限建立多个用户组,把有相应权限的用户放入相应的组中 5.建立项目文件存储目录 sudo mk

SVN 多项目管理(强烈建议每个项目建一个库)

Subversion的目录结构是很自由的,所有的规划都必须是你自己规定,考虑一个 subversion仓库的目录树,你可以把任何一个目录认定为一个项目,你可以只checkout这个目录下的所有文件进行编码,跟CVS不同,CVS显式指定一个个module.所以你可以在一个仓库内保存 多个项目,也可以一个仓库保存一个项目而使用多个仓库.我个人比较喜欢第二种,因为 Subversion的每次commit都会导致整个仓库 版本号增加一个,会使得 多个项目的 版本号出现断层.而且如果 多个项目参与人不同,