版本控制系统
目的
- 版本控制系统用于存储和追踪文件夹和文件的修订历史,从而管理和回溯那些被纳入其管理范围之内的任意对象(包括代码、配置文件、依赖包等)的每一次修订,回答“4个W”,即什么时间(when),修改了什么内容(what),是谁修改的(who)以及为什么修改(why)的问题。
- 版本控制系统是团队合作共同交付软件过程中所用到的重要写作管理机制,支持软件配置管理活动,追踪和记录多个版本的开发和维护活动。
分类
- 集中式版本控制系统:拥有一个单一的集中管理的版本控制管理服务器,保存所有文件的历史修订版本记录,团队成员通过客户端与这台服务器交互来获取需要的文件。缺点如下:1)网络不佳时同步大量文件会经常失败;2)具有单点故障的风险。典型产品Subversion,即SVN。
-
分布式版本控制系统:与集中式不同点在于多个服务器共存,每个人的节点都是一个代码仓库,通常会指定某个节点作为团队的中央服务器。特点在于:commit操作都是在本地进行而无须经过服务器,提交速度快;只有在需要向其他人或服务器做文件提交或同步时,才需要通过网络推送或拉取到远程仓库。目前主流的代表为Git。
基本概念
- 代码仓库:保存一组文件所有历史修订的逻辑单元
- 分支:对选定的代码基线的创建的副本
- 主干:特殊的分支,在代码仓库创建时系统默认创建,比如SVN的trunk分支,Git的master分支
- 版本号:分支上的每次提交编号
- 标签:某个具体版本号的别名,方便记忆和查询
- 头:head,某个分支最新一次提交对应的版本号
- 合入:将一个分支合并到另一个分支
- 冲突:合入操作时如果出现不一致的内容,需要人工介入确认如何修改后方可合入成功
常见的分支开发模式
主干开发,主干发布
工程师向主干上提交代码(或者分支生存周期很短,如数小时或少于1天),并用主干代码进行软件交付。
- 低频发布:常见于一些周期比较长的大型软件开发项目,属于瀑布开发模式,主干代码长时间处于不可用状态,在所有功能开发完之后才进行软件联调和集成测试。
- 高频发布:常见于具有比较完整交付基础设施(自动化配置构建、自动化测试、自动化运维、自动化监控与报警等)的互联网产品团队,具备快速的缺陷修复能力。
- 优点:分支方式简单,分支管理工作量较少
- 缺点:针对低频发布,项目后期的缺陷修复阶段,会造成资源的浪费,所有团队成员都在等待缺陷修复的完成;针对高频交付,多人向主干频繁提交代码,合入的成本和复杂性大大增加,无法保证未开发完的功能不合入发布版本的原则。
主干开发,分支发布
开发人员将代码合入主干,在接近版本发布时,从主干拉出新分支负责集成测试和缺陷修复,质量达标之后进行版本发布。
特点如下:
- 主干代码提交频繁,对主干代码质量的保障有较大的挑战;
- 分支只修复缺陷,不增加新功能;
- 发布分支的生命周期不应该持续时间过长,一段时间后应该终止该分支的任何操作。
- 优点:
- 与将要发布的功能无关的团队成员可以持续工作在开发主干上,不受版本发布的影响;
- 新发布的版本出现缺陷时,可以直接在开发分支上洗浴,不影响主干分支。
- 缺点:
- 主干上的代码通常只针对下一个新发布版本的功能开发,只要有任何一个需求未完成,就不能创建新发布分支;
- 若不对发布分支数量进行约束,容易出现“分支地狱”,降低团队的研发效率。
分支开发,主干发布
最为广泛应用的工作方式。团队从主干上拉取分支,并在分支上开发新功能或修复缺陷;当分支上的功能开发完成后要对外交付版本时,才将代码合入主干,在主干上进行缺陷修复,质量达标之后发布。
优势点
- 在分支合并前,每个分支之间的开发活动是相互独立不受影响的;
- 团队可以自由选择发布哪个分支上的特性;
- 如果新版本出现了缺陷,直接在主干分支或者使用hotfix分支修复,简单便捷。
缺陷
减少了主干合并的频次,延迟了发现缺陷和代码冲突的时间,不利于及时进行代码重构。该分支策略的关键点在于:
- 让主干尽可能一直保持在可发布状态
- 每个分支的生命周期尽量短
- 主干代码尽早与分支代码合并
- 一切以主干代码为准,尽可能不要在各特性分支之间合并代码
分类
- 特性分支模式:以特性为维度,允许多个分支同时进行,且每个分支对应一个功能特性的开发工作,完成之后立马合入主干分支。
- 团队模式:以团队为维度,每组人一个分支,分支上包括一组相近或相关的特性集合开发,一般分支持续时间比特性分支的存续时间长。
分支模式的演化
三驾马车分支模式
维护3个分支,包括开发分支、预发布分支和发布分支。所有开发人员把新功能代码分捡到预发布分支;在预发布分支上只做缺陷修复、文档生成和预发布相关的工作,不做新功能开发;当预发布分支的代码满足发布要求,便合入到发布分支,作为正式版本进行版本发布。
Gitflow分支模式
Gitflow分支模式将三驾马车模式和特性分支模式融合在一起,优点是每个分支的定义都明确且清晰,但是分支较多,容易出现“分支地狱”的问题。
- master分支:正式版本的发布分支
- Release分支:用于质量打磨的预发布分支
- Development分支:新功能开发和集成分支
- Feature分支:为了开发某个功能,从Development分支上拉出的分支;功能完成后合入Development分支
-
Hotfix分支:从master分支上拉取,用于修复缺陷,验证后合入master和Development分支
GitHubFlow分支模式
GitHub团队所使用的分支策略,对开发者的开发纪律要求比较严格,对质量保证手段的要求也很高,开发步骤如下:
- 从master创建一个新分支
- 在新分支上提交新特性代码
- 功能开发完成后并测试通过,创建Pull Request,即PR
-
其他开发人员对PR进行审查,确认质量合格后,合入master
分支策略的选择
企业需要根据开发或维护的软件产品类型,结合发布频率,并考虑自身团队成员能力和基础设施建设情况来确认适合自己的分支方式。
版本发布模式
- 项目制发布模式:先预先确定某一版本所需包含的所有功能特性,在所有功能开发完成之后并达到发布质量标准后进行版本发布,对于版本发布间隙和时间不定,这是典型的瀑布发布流程。
- 发布火车模式:常见于大型套装分发类软件,这类企业间的各个部门之间有相互依赖,为了协同,实现计划约定好版本发布的时间,各个部分严格按照对齐的时间点来对齐开发的进度,一般发布时间较长,以季度为交付窗口,但通常不会超过10个月。
- 城际快线模式:固定版本发布的时间和质量维度,且时间周期相对较短,如一周或一天,针对那些在发布时间已达到固定质量标准的特性进行一次发布,团队成员可以自行决定在哪个版本上线。发布间隔的选择原则是,不影响用户体验和不增加成本且合规,稍微有些紧张感。
分支策略和发布周期的关系
- 分支策略与版本发布周期之间有一定的相关性。
- 通常:软件开发周期极长的“项目制”团队和发布频率极高的“城际快线”团队会使用“主干开发,主干发布的”分支策略;次之的团队是使用“主干开飞,分支发布”的分支策略;他们之间的团队会使用“分支开发,主干发布”的分支策略.
- 它们之间存在着很大的重叠部分,通常受到团队成员人数、产品架构和质量保障基础设施状况的影响。
- 城际快车模式是持续交付2.0所倡导的模式,当发布周期缩短到一定程度后,主干开发模式更具有优势。