引言

网络上版本管理系统之争持久而喧嚣,依照声量来讲目前应该是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. TestNG在Eclipse中运行的几种方法

    目录 1 在Eclipse Outline视图中,点右键run as TestNG Test (不推荐) 2 在Eclipse类编辑界面,直接点击右键run as TestNG Test 3 通过Te ...

  2. 【POJ - 3273】Monthly Expense (二分)

    Monthly Expense 直接上中文 Descriptions 给你一个长度为N的序列,现在要让你把他们切割成M份(所以每一份都是连续的),然后每一份都有一个和sum[i],其中最大的一个是ma ...

  3. 两份简单的logstash配置

    input{http{port=>7474}} filter{ grok{ match =>{ #"message" => "%{COMBINEDAPA ...

  4. 基于SpringBoot从零构建博客网站 - 集成editor.md开发发布文章功能

    发布文章功能里面最重要的就是需要集成富文本编辑器,目前富文本编辑器有很多,例如ueditor,CKEditor.editor.md等.这里守望博客里面是集成的editor.md,因为editor.md ...

  5. 图像反转(一些基本的灰度变换函数)基本原理及Python实现

    1. 基本原理 获取像素值在[0, L]范围内的图像的反转图像,即为负片.适用于增强图像中白色或者灰色的区域,尤其当黑色在图片中占主地位时候 $$T(r) = L-r$$ 2. 运行结果 图源自ski ...

  6. Thread、ThreadPool、Task、Parallel、Async和Await基本用法、区别以及弊端

    多线程的操作在程序中也是比较常见的,比如开启一个线程执行一些比较耗时的操作(IO操作),而主线程继续执行当前操作,不会造成主线程阻塞.线程又分为前台线程和后台线程,区别是:整个程序必须要运行完前台线程 ...

  7. java实现发短信功能---腾讯云短信

    目录 java实现发短信功能 前言 开发环境 腾讯云 ---短信 代码 效果 结束语 java实现发短信功能 前言 如今发短信功能已经成为互联网公司的标配,本篇文章将一步步实现java发送短信 考察了 ...

  8. 从Maven私服获取依赖

    通过Internet直接从Maven公用仓库获取依赖包是默认配置.不过对于中国软件公司来讲,访问这些公用仓库通常较慢,对于一些管理严格的不能直接上网的软件公司来讲,这更加是不可能的.Maven项目可以 ...

  9. JS判断字符串长度,结合element el-input el-form 表单验证(英文占1个字符,中文汉字占2个字符)

    首先看看判断字符串长度的几种方法(英文占1个字符,中文汉字占2个字符) 方法一: function strlen(str) { var len = 0; for (var i = 0; i < ...

  10. Keras载入mnist数据集出错问题解决方案

    找到本地keras目录下的mnist.py文件 通常在这个目录下. ..\Anaconda3\Lib\site-packages\keras\datasets 下载mnist.npz文件到本地 下载链 ...