几种常见的分支模型
github分支模型
在线演示:Understanding the GitHub flow
说明:
- 只有一个长期分支:master分支,使用起来非常简单;
- 开发新的改动或者特性的时候,拉取一个新的分支
branch-a
; - 开发完成,发起
pull request
,在这个过程中可以进行代码评审
,优化代码重新发起pull request
; pull request
被接受之后,合并到master,则删除此分支branch-a
这种模式对开发人员要求比较高,代码质量主要靠开发人员单元测试,
pull request
代码审查保证。另外,目前github平台中可以集成Jenkins
做持续集成的自动化构建测试,当然,你也可以定制一些自动化测试用例,用来进一步保证代码的质量。
gitlab分支模型
gitlab flow 的分支模型分为两种情况:
持续发布项目的分支模型:
master分支作为开发分支,不同环境分别建立对应的分支,如预发布环境PRE-PRODUCTION
分支,生产环境PRODUCTION
分支。代码的改动只能从上游分支到下游分支:
master --> pre-production --> production
版本发布的分支模型
这种模型,代码提交到master,每一个版本都拉取一个版本分支,如上图的2-3-STABLE
,2-4-STABLE
,如果生产环境出现了bug,仍然是从master进行bug修复,修复完成之后再把修复cherry-pick
到版本分支进行发版(可以在这个时候给这个版本升级一个小版本号,如2-3-1-STABLE)。
延伸阅读:GitLab Flow
gitflow
这个是业界最通用改动一个分支模型。
优点:
- 基本满足瀑布开发模型,敏捷开发等所有的开发模型;
缺点
- 分支较多,管理比较复杂;
- 分支生命周期越久,越落后主干版本,需要定期合并主干代码,不利于持续集成;
其他分支模型
还有另一种分支模型,是从gitflow
演变过来的,做了一些调整,如下:
其中传统的gitflow分支模型,可以通过develop
分支做集成,并且在develop分支上面改bug,而上面这种分支模型是在develop分支做集成测试,但是还是在原有特性分支修复bug,这样做的:
好处:
- 方便制定发版版本特性,不会一个特性有问题连累整个版本的发布。
坏处:
- 特性分支生命周期进一步延长,增加了分支的维护成本;
- 不利于做持续集成
延伸:持续集成的最佳实践是越少分支越好,开发完成,尽早在开发分支上测试回归。至于上面提到的问题,可以通过
抽象模拟分支
,开关控制特性是否开启
的方式解决,详细阅读《持续交付:发布可靠软件的系统方法》一书。不过这种方式要求更高的编程水平,简化了分支的复杂度,但是增加了代码的复杂度。
Facebook分支模型
从Facebook的版本流程说起:
对应的分支模型:
对应的审查代码流程:
优势
- 1、未审核代码不发布到远程仓库,支持打回修改,因为未审核的代码是不稳定、易变的,不应该推送到远程仓库;
- 2、在推送代码之前就可以通过代码审查保证代码质量,避免后期修改成本剧增;
持续构建过程中,一些保证系统质量原则:
-
- 写完代码之后,尽可能快的做代码评审,趁热打铁;
-
- 在提交代码评审之前,需要做充分的单元测试和静态代码检测;
-
- 在提交代码评审的说明中充分说明你所实施的测试计划;
-
- 在代码审查通过之后合版到主分支并且自动构建,触发自动化测试;
-
- 新功能由测试人员进行冒烟和边界测试,同时需要有测试人员编写自动化测试脚本;
-
- 测试环境每隔几个小时在主分支进行一次自动化测试:包括构建测试、集成测试(冒烟)、性能测试…
延伸:
来自Palantir的代码评审最佳实践:讲述了代码评审的动机,评审的要点,评审的实际;
Google如何做代码评审:讲述了Google里面的评审最佳实践,以及代码评审工具;
Facebook中的代码评审工具
以下是市面主流的代码评审工具的介绍:
特性 | Phabricator | Gerrit | Gitlab | Github |
---|---|---|---|---|
以小的推送快速推进评审 | √ | √ | × | √ |
入库前接受评审 | √ | √ | × | × |
命令行发起评审 | √ | √ | × | × |
测试结果接入与展示 | √ | √ | × | √ |
灵活接入发布系统 | √ | √ | √ | √ |
评审单子状态跟踪 | √ | × | × | × |
评审报表 | √ | × | × | × |
评审通过条件灵活设置 | × | × | × | √ |
评审问题分类 | √ | × | × | × |
静态代码分析或者自动化单元测试 | √ | × | × | × |
Facebook内部主要使用了Gerrit
和Phabricator
工具,其中Phabricator
是Facebook的一个开源项目。通过对比发现母亲Phabricator
比较强大。
工作中分支模型改进的思考
我们希望工作中的分支模型越简单越好,目前存在的一些问题:
- dubbo项目有比较多的api,以及公共lib包,能否让这些lib包只保持一个分支?
- 如何降低lib包版本号的维护成本?
- 能否尽量缩短特性分支的声明周期,一旦自测完成,立即合并到master分支,并且通过特性开关控制是否开启?
相关启发:
Reference
Continuous Deployment of Mobile Software at Facebook
关于两种CI/CD策略以及git分支模型的思考
The Facebook Mobile Release Process
GitHub Flow
Understanding the GitHub flow
Git 工作流程(Git flow, Github flow flow, Git lab flow)