引言

网络上版本管理系统之争持久而喧嚣,依照声量来讲目前应该是Git占了较大的优势。不过我们本文的关注点在于代码的分支管理模型,因为大家无论是用SVN或者Git,目的是为了解决研发过程管理中的实际问题。我这里整理几种分支管理模型,这样大家可以对照自己的痛点选择合适的模型。不过并不是最灵活的方案就最好,灵活意味着分支的管理和具体研发学习曲线都更复杂。

我先根据实际生产过程中企业面临的问题列出一个清单:

  • 学习曲线(Complexity)
    企业都希望研发团队能够快投入生产,而在版本管理这种“小事”不要花费太多精力。
  • 需求变更(Release)
    企业在一个迭代过程中是否能够完全不进行需求的变更,无论你们的周期是两周、一个月、或者一季度。
  • 线上修正(Hotfix)
    系统目前是否已经非常稳定,不存在需要发布线上修正的可能。
  • 多环境(CI/CD)
    企业是否存在多环境的要求(测试、预发布、正式等)
  • 长期需求(Long-Lived Version-control Story)
    企业是否存在一个大需求可能要持续数个迭代。(例如底层的基础业务模型扩展,增加新的数据隔离标识字段,涉及到系统底层或者全系统业务逻辑的变更。这里列这种需求并不是说必须支持,有些普通需求由于错误的技术方案/市场的变化等情况就会变化成这样的需求,所以综合考虑边界情况。)

另外也交代一下我所在的公司背景:
我们是一家企业内部学习培训的人力资源SAAS管理平台,对于平台改进有自己的规划和目标,但是又面临着大客户的定制化需求以及交付时间压力。技术栈还是Java和.Net 双栈并存,所以可以说是最复杂的研发环境了。我们也慢慢衍生出了自己的一套改进的代码版本管理模型。

TrunkBased

原理1:研发团队在名称为 Trunk 的单一分支进行开发,当开发工作到一定阶段的时候达到可发布条件后,切出Release分支进行发布,并且Release分支是不可以修改的仅仅做发布使用。大部分SVN用户是基于本模型进行开发。
适合小团队的模型,大家都直接在Trunk上进行开发

适合较大团队的模型,大家切出短期的特性分支进行开发,完成后合并回Trunk。

适用场景:适合于单一稳定产品线,迭代排期稳定,需求边界完全可控的团队。
优点:模型简单
缺点:

  • 线上修正:按照上图目前系统已经发布了12.1,下一个迭代也在开发中,线上发现了问题。由于Release分支是禁止修改的,而Trunk此时包含了新的特性代码无法发布,就造成了线上异常无法修复。
  • 需求变更:无法支持,已经提交到Trunk的内容抽离很困难。
  • 多环境:无法支持
  • 长期需求:无法支持

总结:Trunk Based最大的优势就是清晰简单,付出的代价就是灵活性,基本可以说不存在任何灵活性。适用的场景我觉得是进入到后期维护的大型系统,不会做太多的变更并且不会有太多的突发问题。

GitFlow

GitFlow来源应该是 Vincent Driessen 在2010年1月发表的这篇《A successful Git branching model》,基本是现在Git中最出名的流程管理方法了。

这张图相信大家都不陌生。
原理:
主要分为5个分支

  • master分支存放所有正式发布的版本,可以作为项目历史版本记录分支,不直接提交代码。仅用于保持一个对应线上运行代码的 code base。
  • develop分支为主开发分支,一般不直接提交代码
  • feature分支为新功能分支,feature分支都是基于develop创建的,开发完成后会合并到develop分支上。同时存在多个
  • release分支基于最新develop分支创建,当新功能足够发布一个新版本(或者接近新版本发布的截止日期),从develop分支创建一个release分支作为新版本的起点,用于测试,所有的测试bug在这个分支改。测试完成后合并到master并打上版本号,同时也合并到develop,更新最新开发分支。(一旦打了release分支之后不要从develop分支上合并新的改动到release分支),同一时间只有1个,生命周期很短,只是为了发布。
  • hotfix分支基于master分支创建,对线上版本的bug进行修复,完成后直接合并到master分支和develop分支,如果当前还有新功能release分支,也同步到release分支上。同一时间只有1个,生命周期较短。
    适用场景:处于前中期的大型项目,人员较多管理场景较复杂,但是迭代相对稳定,周期内不会频繁的变更需求,尽量不要开长需求分支。
    优点:
    能够支持线上修正、多环境
    缺点:
  • 复杂度稍高
  • 需求变更:不够灵活,由于主分支实际上是基于develop,那意味着一旦代码提交上去,一段时间后需要撤销(本次迭代不发布)就比较困难

总结:Gitflow已经很偏向互联网风格的代码管理,考虑到了多环境、线上修正。而且现在很多IDE或者工具有整合了GitFlow的插件使用起来会更简单。对于有良好规划和进度控制的项目,应该是已经够用了。但是对于一些有交付日期的,但是需求池可以调整的项目可能还不够灵活。

AoneFlow

阿里的研发效能事业部专家基于TrunkBased和GitFlow提出了一套新思路:AoneFlow
原理:AoneFlow 只使用三种分支类型:主干分支、特性分支、发布分支,以及三条基本规则。

  1. 开始工作前,从主干创建特性分支。

  2. 通过合并特性分支,形成发布分支。

  3. 发布到线上正式环境后,合并相应的发布分支到主干,在主干添加标签,同时删除该发布分支关联的特性分支。

缺点:

  • 复杂度稍高
  • 多环境:由于没有develop分支所以可能测试环境构建会有一些问题。
    优点:
  • 线上环境,长期需求都是支持的

总结:AoneFlow最重要的点,就是保证master分支可用和随时可发布,其他可能都是临时分支。所以取名的时候应该是Ali-One-Flow,这个含义。临时分支的组装就有很多种玩法了,需要企业根据自己的需要来定制处理。

OneFlow

OneFlow我找到两个版本,一个是国内版本,一个是国外的版本
国内版本:
原理:此模式是TrunkBased的升级版,增加了Hotfix分支,采用多主干模式,一般是双主干(一个主干分支+一个主干发布分支)。OneFlow在TrunkBased模式演进中,做了一此改善,分离了主干分支和发布分支,有效的规避了一些问题。但是同样还不能满足多版本,多产品的并行开发。
国外版本:
原理:此模式是GitFlow的简化版本,但是(作者认为)并不比GitFlow逊色。主要也就是双分支2,除了主干分支,只会额外保持一个分支,在不同的阶段切除特性、发布、修正分支

而且还提供了变种版本,master+develop 双主干分支的模式。

总结:国外版本的OneFlow发表在2017年,我觉得他确定了基于一个,最多两个的固定分支进行开发这种原则。提供了企业版本管理过程中的最佳实践原则,(我觉得)也启发了AoneFlow这种优秀的Flow。

ExeFlow

ExeFlow是我们公司目前在使用的代码管理流程的名称,主要是吸取了AoneFlow的思想,同时根据我们自己的环境进行一些流程和分支的固化。
要理解这个Flow流程,首先基于我们的实际工作场景:
我们的系统由于主要是面向大型企业内部使用,存在复杂的分发流程和权限控制,经过长时间的累积业务模型也很复杂各种关联和引用,所以有一些大型任务的开发周期可能会比较长,到达2-3个月的周期。
我们的迭代周期正常是1个月。流程大概如下:

  • 上月末进行迭代计划评估与安排,这里会确认下月迭代目标的Story内容与数据。各自主管进行子任务的拆分评估与排期。
  • 开发时间一般是2周,我们基本是会在月中设定研发截止线,所有研发任务要在截止线前完成提测。期间有完成的任务可以随时提测。【涉及分支:Feature,Local,Develop】
  • 完整的系统集成测试时间一般是安排在第三周,测试会进行全面的测试。本周研发的主要任务一方面是处理Bug,一方面可以介入下月迭代大项的需求说明与分析。【涉及分支:Feature,Local,Develop】
  • 第四周的前三天,我们会切出预发布的分支在第四周周一时,会给出明确本次能够上线的Story List,不在清单内的都不允许合并只预发布环境(也就是我们实际上运行需求在预发布之前仍旧有变更,只要测试人员通过了集成测试环境,就可以合并并且发布),本次发版的具体内容和通知也是当天发出。【涉及分支:Feature,Release】
  • 发版一般安排在当月的最后一个周四(为了防止有线上问题,所以不能是周五第二天会没有人员值守)。【涉及分支:Release,Master】

主要经历了2个大版本的变化
版本1,基本是参考GitFlow

这个版本的固定独立分支是三条:Master,Develop,Local。核心在于Release分支还是由Develop建立,对于需求变更的支持性不够灵活。

版本2,是参考AoneFlow

(上图就是使用gitgraphjs绘制的)
这个版本的固定独立分支也还是是三条:Master,Develop,Local。
但是核心差异在于Release分支是由Master建立,并且合并需要上线的Feature分支,而Release分支在我们企业的流程中只会存在2-3天的时间。

总结:其实是比较复杂的流程,而且研发的操作的内容实际更多。我们还要锁定某些分支,设定权限管理。但是解决了我们的问题,所以从上到下都能替换到复杂流程带来的好处。

综述

如果你完整看完了这篇文章,实际上现在需要的并不是马上选择当前企业应该选用哪一种Flow管理模型,而是认真的思考企业实际面临的问题和痛点。越灵活的流程越复杂,对于研发人员初期的接收难度就越高。我们想真正让研发团队理解并接受某个管理模型,最重要的是这个东西解决了企业面临的问题。才能让管理层、研发自身体会到好处。
我看了很多版本管理软件的对比,无论是抬Svn打Git或者反之,我觉得都对也都不对。因为无论管理或者技术,本身没有对错优劣,问题是场景。如果一个简单稳定的后期维护项目,强推复杂的管理流程,效果不会好,因为没有解决任何问题,只会引入问题。
管理的核心在于解决问题,而不是管理行为本身


  1. 引用自Trunk Based Development Introduction

  2. 画图工具是使用gitgraphjs

企业代码版本管理之争:TrunkBased vs GitFlow vs AoneFlow vs OneFlow vs ExeFlow的更多相关文章

  1. 10年经验17张图带你进入gitflow企业项目代码版本管理的最佳实践

    前言 对于项目版本管理,你是否存在这样的痛点:项目分支多而杂不好管理,git log界面commit信息错乱复杂无规范,版本回退不知道选择什么版本合适--. 项目版本管理的最佳实践系列,笔者将以两篇文 ...

  2. svn代码版本管理总结

    svn代码版本管理 1.0开发,做dev1.0的branch此时的目录结构svn://proj/             +trunk/ (不负担开发任务)             +branches ...

  3. 代码版本管理/SVN/Git

    代码版本管理 一.SVN 1.SVN diff(create patch) 遇到了一个问题: Index: 通信协议.doc ===================================== ...

  4. 使用Git进行代码版本管理及协同工作

    Git简介: git是一种较为先进的代码版本管理及协同工作平台,采用分布式文件块存储: 1.  分布式: 代码保存在所有协同成员的计算机上,网速较差时依然可用:而传统的集中式代码版本管理系统则较难脱离 ...

  5. Git 结合Git使用Bitbucket进行代码版本管理流程规范与实践

    结合Git使用Bitbucket进行代码版本管理流程规范与实践   By:授客 QQ:1033553122   目录 目录 1 一. 测试环境 2 二. 新建项目 2 三. 新建公有版本库 3 四. ...

  6. $SVN代码版本管理工具的使用

    SVN是一种代码版本管理工具,具有可视化的操作界面,使用简便,和git的功能类似.下面总结一下SVN的基本用法: 1.安装SVN软件,和安装一般的软件的步骤差不多,这里使用的版本是TortoiseSV ...

  7. 实验一 GIT 代码版本管理

    实验一  GIT 代码版本管理 实验目的: 1)了解分布式分布式版本控制系统的核心机理: 2)   熟练掌握git的基本指令和分支管理指令: 实验内容: 1)安装git 2)初始配置git ,git ...

  8. 实验一  GIT 代码版本管理

    实验一  GIT 代码版本管理 实验目的: 1)了解分布式分布式版本控制系统的核心机理: 2)熟练掌握git的基本指令和分支管理指令: 实验内容: 1)安装git 2)初始配置git ,git ini ...

  9. 实验一Git代码版本管理

    GIT代码版本管理 实验目的: 1)了解分布式分布式版本控制系统的核心机理: 2) 熟练掌握git的基本指令和分支管理指令: 实验内容: 1)安装git 2)初始配置git ,git init git ...

随机推荐

  1. VS、C#配置R语言开发环境

    R语言学习笔记(一)——在Vs.C#中配置R语言开发环境. 最近在学习小众的R语言,所以将遇到的问题记录下来供大家参考,不足之处欢迎大家交流指正. 至于R语言的介绍就不多说了,它集成了复杂的数学算法, ...

  2. C# 委托(delegate)、泛型委托和Lambda表达式

    目录 # 什么是委托 # 委托声明.实例化和调用 1.声明 2.委托的实例化 3.委托实例的调用 4.委托完整的简单示例 #泛型委托 1.Func委托 2.Action委托 3.Predicate委托 ...

  3. 【iOS】this class is not key value coding-compliant for the key ...

    一般此问题 都是由 interface build 与代码中 IBOutlet 的连接所引起的. 可能是在代码中对 IBOutlet 的名称进行了修改,导致 interface build 中的连接实 ...

  4. K8S 部署 Web UI

    在早期的版本中 Kubernetes可以在 Dashboard 中看到 heapster 提供的一些图表信息, 在后续的版本中会陆续移除掉 heapster,现在更加流行的监控工具是 promethe ...

  5. 安装使用xen虚拟化工具

    换了一家新公司,需要拿出一套虚拟化方案,就把业界的主流虚拟化技术划拉了一遍,给领导交了一份报告,具体的技术部分已经在之前的随笔里了,本篇文章主要介绍的是xen虚拟化工具的安装: Xen官方部署文档:h ...

  6. .net持续集成测试篇之Nunit常见断言

    系列目录 Nunit测试基础之简单断言 在开始本篇之前需要补充一些内容,通过前面搭建Nunit测试环境我们知道要使一个方法成为单元测试方法首先要在此方法所在类加上TestFixture注解,并且在该方 ...

  7. 03-Django模型类

    ORM框架:对象-关系-映射 将面向对象语言程序中的对象自动持久化到关系数据库中.本质就是将数据从一种形式转换到另外一种形式O表示Object 对象类R表示Relations 关系,关系数据库中的表M ...

  8. 洛谷P2763题解

    吐槽一下:蜜汁UKE是什么玩意?! 题目分析: 观察题面,对于给定的组卷要求,计算满足要求的组卷方案,可以发现这是一道明显的有条件的二分图匹配问题,于是考虑建模. 建一个超级源点,一个超级汇点:源点与 ...

  9. 十分钟带你看一遍ES6新特性

    let , const关键字 var 看习惯了java, 看js真的是忍不住想笑,比如说这个var,它太自由了,自由到{}根本限制不住它的生命周期 js的var关键字,无论在何处声明,都会被视为声明在 ...

  10. java 各基本类型转 bytes 数组

    java 将 基本类型转byte[] 数组时,需考虑大端小端问题 1. 大端格式下,基本类型与byte[]互转 BigByteUtil.java package com.ysq.util; impor ...