[转]源代码的管理和发布:以SVN为例
FROM : http://ju.outofmemory.cn/entry/47277
前几天在微博吐槽了SVN的几个不爽的地方:.svn文件满天飞、分支管理的麻烦。不爽一般来说都是有过对比后才有如此感觉,比如:相比于Git;或者你对该事物了解不够,比如:.svn的问题,其实早在1.7版本中已经解决了。
至于分支管理,如果把控好,再加上项目本身代码质量足够高,其实也没那么麻烦。如果觉得麻烦,可能很大程度上,是项目的代码本身就很糟糕,造成管理上的麻烦,比如:要修改个特性,估计需要一段时间,为了不影响主干代码稳定,需要在分支中开发,到合并代码的时候就各种麻烦,但觉得麻烦其实很多时候是因为代码耦合度太高了。
下面有关SVN代码的管理和发布,其描述前提是团队成员往SVN贡献的代码,质量都是足够高的,并且前提是开发商业软件,会有钱、时间、质量这坑爹3角因素的影响,而不同于开源项目模式。
目录布局回顾
先简单回顾下SVN的目录布局吧。
项目在版本仓库中的目录
trunk、branches、tags,这是一个项目在版本仓库中典型的目录布局。
- trunk:主干,如果说把一个软件项目从开始到消亡比作一个故事的话,主线情节都在这里被SVN记录着。
- branches:分支,有很多种用法,比如:版本发布维护分支、新特性开发分支,甚至是缺陷修复分支等等。
- tags:标签,或者叫快照,某个版本发布时候,都在这里留档。
示例如下图:
不同版本仓库
对于一个比较大的项目,可能会拆分为多个子项目,各个子项目团队,按照约定各自进行开发;或者一个公司有很多项目,每个项目团队都各自进行开发。无论哪种情况,这个时候版本仓库的建立有2种选择,公用和独立,其实对于使用SVN客户端的程序员来说没太大区别,唯一不同的是前者是公用一套SVN版本号,而后者是独立使用各自的SVN版本号的。而在这个问题上,SVN又不同于Git,Git的所谓版本号就可以认为全球都唯一,甚至全宇宙唯一?哪怕不同公司的版本仓库。
其实上面说的版本仓库的管理,理解上就可以认为是目录管理,再加上时间这个维度。下面以可能出现的三种情况作为例子,来说明SVN代码的管理和发布。
适合小团队情况
小团队,不同人的理解可能不同吧,这里就定量一下规模,索性特指2-4人水平都一样的小团队吧。在人员较少的情况下,如何来控制trunk、branches、tags这3者的关系?其实最简单的方式是大家都在trunk上贡献代码,觉得某个版本差不多了就tags一下,相当于和branches说拜拜了。
但这里其实会有几个问题:
- 要开发某个特性,会花费挺长时间,这段时间不提交代码不合适,提交了又会影响trunk代码稳定性,怎么办?
- 觉得差不多了是什么概念?能保证发布了某个版本测试没问题?保守点考虑,还是认为会有各种问题,需要严格测试,定量了,如果发现问题还得进行缺陷修复吧。
- 这个时候,另一个问题出现了,发布这个版本的那段时间,团队中的1-2个人完成本次版本的开发了,又想进行下个版本的开发工作,岂不是得停滞了,因为他们也不知道当前发布的版本有没有问题。
针对上述几个问题,可以尝试下下图的模式,但需要配合几个其它实践,保证迭代质量。
上图的意思,还是2-4人的小团队,集中战力在trunk进行新版本研发+旧版本维护,只不过区别就是,到了上面说的觉得差不多了,新的大版本或旧版本的某个小版本代码稳定的时候,分出去一个发布分支,由1-2个人严格配合测试,在该分支上工作,有需要修复的缺陷,有人在trunk上修复了,可以直接把该修复merge到发布分支上。
这里约定,新版本主要进行新特性的发布;旧版本进行旧特性的问题修复。但这里有个疑问,新特性的代码和旧特性的代码都在一起,那发布旧版本问题修复版本时候,新特性的代码咋办?这里就得用到其中1个实践,叫做“特性开关”,虽然新特性的代码已经提交到trunk,但发布旧版本的问题修复版本时候,该特性不会开放出来。对于用户来说,这个还是个旧版本的缺陷修复版本。
新特性的研发,必然伴随着代码的不稳定,代码质量的下降,这个时候就得用到另外2个实践,“trunk上每次代码提交进行codereview”和“每次代码提交的持续集成”,说白了就是每次代码提交都要有充分的反馈,如果团队的codereview习惯足够好,以及项目本身有了一套成熟的持续集成的话,就能一定程度上避免这个问题,如果发现有问题,立马反馈,及时修正。
还有最后一个疑问,都在trunk中,怎么保证新特性的代码和旧特性的代码管理起来足够分离?这个就得考验团队的设计能力时候了,是否能让各个功能模块间的耦合度足够低,从而把影响降低,说白了还得程序员足够厉害。当然这里说的“特性开关”不要太多,2-4人的小团队,2个大的特性开关已经很复杂了。如果这种开关很多咋办?这个时候其实不是你们团队从技术层面或管理层面需要解决的问题了,很有可能是当前的功能必须要更多人维护开发,就是需要扩充团队了;或者,根本不需要这么多功能特性,直接砍功能吧。
下面讲一个理想模型,比如项目资金流能撑得起更多的团队人员的情况下,如何更高效的研发。
比较流行的、推荐的
直接看图,跟上图很类似,区别就是,新特性研发trunk和旧特性维护branches分开来了,并且由2个小组分别负责:
- 红色外框代表小组1,一开始是新特性开发小组,该特性发布后,就变成旧特性维护小组了。
- 蓝色外框代表小组2,一开始可能是旧特性维护小组,另一个小组进行维护他们开发的特性的时候,这个小组角色就变成新特性开发小组了。
- 当然两组是实力相当的小组,他们来回切换新特性开发和旧特性维护。
- 并且能保障新版本研发和旧版本维护可以同时进行。
为了更好说明,直接引用一段SVN官方文档的故事描述
http://svndoc.iusesvn.com/svnbook/1.4/svn.branchmerge.commonuses.html#svn.branchmerge.commonuses.patterns
发布分支
大多数软件存在这样一个生命周期:编码、测试、发布,然后重复。这样有两个问题,第一,开发者需要在质量保证小组测试假定稳定版本时继续开发新特性,新工作在软件测试时不可以中断,第二,小组必须一直支持老的发布版本和软件;如果一个bug在最新的代码中发现,它一定也存在已发布的版本中,客户希望立刻得到错误修正而不必等到新版本发布。
这是版本控制可以做的帮助,典型的过程如下:
* 开发者提交所有的新特性到主干。 每日的修改提交到/trunk:新特性,bug修正和其他。
* 这个主干被拷贝到“发布”分支。 当小组认为软件已经做好发布的准备(如,版本1.0)然后/trunk会被拷贝到/branches/1.0。
* 项目组继续并行工作,一个小组开始对分支进行严酷的测试,同时另一个小组在/trunk继续新的工作(如,准备2.0),如果一个bug在任何一个位置被发现,错误修正需要来回运送。然而这个过程有时候也会结束,例如分支已经为发布前的最终测试“停滞”了
* 分支已经作了标签并且发布,当测试结束,/branches/1.0作为引用快照已经拷贝到/tags/1.0.0,这个标签被打包发布给客户。
* 分支多次维护。当继续在/trunk上为版本2.0工作,bug修正继续从/trunk运送到/branches/1.0,如果积累了足够的bug修正,管理部门决定发布1.0.1版本:拷贝/branches/1.0到/tags/1.0.1,标签被打包发布。
整个过程随着软件的成熟不断重复:当2.0完成,一个新的2.0分支被创建,测试、打标签和最终发布,经过许多年,版本库结束了许多版本发布,进入了“维护”模式,许多标签代表了最终的发布版本。
你会发现其实很多开源项目就是这么干的,这种模式很通用,不仅限于使用SVN的情况下。
稳定的、干净的trunk
再更进一步,如果项目规模很大,需要参与的人员较多,这个时候代码管理需要更为严格,需要对代码提交要求严格,保持trunk足够稳定、足够干净,可能就会有很多分支出现,比如常见的特性分支,甚至是修复一个缺陷,也会开一个缺陷分支,经过严格的codereview后再merge到trunk或某个维护分支,该实践会牺牲一定的灵活性,给团队成员带来繁琐的感觉,并且迭代起来会慢,建议谨慎使用,如果要用,得有足够理由。示意图如下:
习惯上,如果项目很大,一般都会拆分为多个子项目,各个子项目的各个团队都分别按小团队作战,来避免上述情况,从而提高迭代速度。
或者从工具使用上,可能这个时候使用的是Git,就能更好的解决类似问题,这个在以后的文章中有机会单独说下。
结束
来个箴言作为结束吧:
童子军规则,“要让离开时的营地比进入时更加干净”
类比到写代码,“让模块签入(check in)的时候比签出(check out)的时候更整洁”
再装X些,“做人也是,你离开世界的时候能让世界变得更美好,哪怕一点也行!”
[转]源代码的管理和发布:以SVN为例的更多相关文章
- App开发流程之源代码Git管理
base项目已经可以编译运行了,只不过没有实际功能而已.继续完善base项目前,我们需要考虑一下代码管理的事情了. 不管是一个人开发还是一个团队开发,对源代码进行版本管理是必须的,任何人对代码的的任何 ...
- 15分钟在阿里云Kubernetes服务上快速建立Jenkins X Platform并运用GitOps管理应用发布
本文主要介绍如何在阿里云容器服务Kubernetes上快速安装部署Jenkins X Platform并结合demo实践演示GitOps的操作流程. 注意:本文中使用的jx工具.cloud-envir ...
- Docker-compose 多个Docker容器管理:以MYSQL和Wordpress为例
搬砖的陈大师版权所有,转载请注明:http://www.lenggirl.com/tool/docker-compose.html Docker-compose 多个Docker容器管理:以MYSQL ...
- 源代码的管理与在eclipse中使用maven进行代码测试
管理源代码的工具 开发历史记录 SVN :集中式的源代码管理工具 通常必须连到公司的服务器上才能正常工作 (提交代码,查看代码的历史记录 查看代码的分支) 在公司中开发项目时 每天必须至少提交(Com ...
- [源码管理] Windows下搭建SVN服务器
前文所述SVN客户端使用的时候,用的SVN服务器通常为外部,例如Google Code的服务器,不过,做为一个程序开发人员,就算自己一个人写程序,也应该有一个SVN版本控制系统,以便对开发代码进行有效 ...
- Microsoft强大团队(源代码)管理工具--TFS2010 与vs结合
今天看了与vs 集成原理工具 TFS 2010, 角色分配.项目管理.开发源代码管理.任务分配管理.测试文档管理及跟踪等管理流程.代码版本的分支与合并等等,功能好强大啊. 以下将其安装配置简要介绍(以 ...
- 代码管理(四)SVN和Git对比
在日常运维工作中,经常会用到版本控制系统,目前用到最广泛的版本控制器就是SVN和Git,那么这两者之间有什么不同之处呢?SVN(Subversion)是集中式管理的版本控制器,而Git是分布式管理的版 ...
- Git学习总结(13)——使用git.oschina作为自己的源代码在线管理库
工作有几年了,期间积累了很多的代码片段,一直想找个存放的地方,方便随时的取用.以前可能是放在自己电脑的硬盘中,但毕竟这样使用起来还是有很多不便. 下面通过码云来说明 一下设置过程.其实,码云和GitH ...
- 一个小型的CMS后台管理平台发布啦~
由于我不太懂怎么把博客园里我上传的文件共享,所以只好先放到百度网盘里了 数据库和发布的网站都放在这里 http://pan.baidu.com/s/1eQw3DOA 有问题请参考以下链接: http: ...
随机推荐
- 设计模式 之 装饰者(Decorator)模式
装饰者模式(Decorator):动态地为一个对象添加一些额外的职责,若要扩展一个对象的功能,装饰者提供了比继承更有弹性的替代方案. 结构图: 抽象构件类(Component):给出一个抽象的接口,用 ...
- .NET项目工程生成一份项目帮助文档chm--Sandcastle工具
Sandcastle的,由Microsoft创建的,是从创建MSDN风格的文档中使用的工具.NET程序集和关联的XML注释文件.目前的版本是 2010年6月发布.这是命令行并没有GUI前端,项目管理功 ...
- 区别和详解:js中call()和apply()的用法
1.关于call()和apply()的疑点: apply和call的区别在哪里 什么情况下用apply,什么情况下用call apply的其他巧妙用法(一般在什么情况下可以使用apply) 2.语法和 ...
- yii2 rbac权限控制详细操作步骤
作者:白狼 出处:http://www.manks.top/article/yii2_rbac_description本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出 ...
- yii2使用多个数据库的案例
作者:白狼 出处:http://www.manks.top/article/yii2_%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8_config 本文版权归作者,欢迎转载, ...
- [PL/SQL]oracle数据库的导出导入
一.PL/SQL Developer工具一般对oracle的导入导出有以下4中方式: 1.Oracle导出导入方式 这种方式导出导入为.dmp的文件格式,.dmp文件是二进制的,可以跨平台,还能包含权 ...
- jenkins打包成功,部署失败
环境一直正常,更新了tomcat版本后自动部署报错 ERROR: Publisher hudson.plugins.deploy.DeployPublisher aborted due to exce ...
- 十五天精通WCF——第十一天 如何对wcf进行全程监控
说点题外话,我们在玩asp.net的时候,都知道有一个叼毛玩意叫做“生命周期”,我们可以用httpmodule在先于页面的page_load中 做一些拦截,这样做的好处有很多,比如记录日志,参数过滤, ...
- 记一次使用openrowset 的坑
前几天被老大训斥连openrowset 都不会用,然后我就去看了文档,想测试一下栗子~ openrowset 的具体语法我就不贴了,戳这里:https://msdn.microsoft.com/zh- ...
- tomcat黑/白名单设置
vim $tomcat_home/conf/server.xml(可以单个IP或者多个ip,多个ip用|分隔,支持正则) <Context path=" reloadable=&quo ...