|
导读:编写代码,是软件开发交付过程的起点,发布上线,是开发工作完成的终点。代码分支模式贯穿了开发、集成和发布的整个过程,是工程师们最亲切的小伙伴。那如何根据自身的业务特点和团队规模来选择适合的分支模式呢?本文分享几种主流 Git 分支模式的流程及特点,并给出选择建议。 % p5 o: b' ?, U) Z3 Y: I% u分支的目的是隔离,但多一个分支也意味着维护成本的增加。我们可以分别从开发和发布分支的多寡,做个简单组合,即: : ^; |. E$ O! D+ T' S
设想两个不同的场景:
主流的分支模式 常见的分支模式有 TBD(即主干开发模式)、Git-Flow 模式、Github-Flow 模式及 Gitlab-Flow 模式。 TBD(主干开发模式) 即所有开发者,仅在一个开发分支(即主干)上进行协作开发的模式,在这种模式下,不允许新建任何长期存在的开发分支,有且仅保留主干分支进行开发协作。! q8 |' F' N* m2 T 因为没有长期分离的其他开发分支,任何代码变更持续地更新到主干上,在一定程度上避免了 merge 代码带来的困扰。同时,在这种开发模式下,建议采用发布分支的策略,根据软件版本的发布节奏拉出发布分支。在 TBD 模式下,所有的修改都是在主干上,哪怕是缺陷的修改也是,修改完缺陷后,再 cherry pick 到发布分支上。 其特点总结一下就是: 9 c, M2 |( S; t- v
8 X4 M# M: a6 E9 V: t% x
因为主干开发要求每次变更提交都要小,并且要快速验证完,保证主干是处在可发布状态。对于一些处在开发过程中的特性,如每次变更提交,并非意味着完整特性的完成,为了隔离“特性半成品”对主干的影响,一般会采用特性开关(Feature Toggle)的方式进行隔离。即频繁的代码变更提交,可以先做集成及验证,但是在发布的角度,通过(Feature Toggle)先隐藏相关特性,只有当特性都完成之后,才打开开关,特性完全透出。, S9 ]) R7 J4 g+ _+ Z 但是,特性开关的引入也并不是没有成本,因为特性开关是配置,本质上跟我们常常用到的宏定义(#if #else)没啥区别,从本质上,它也是一种代码的分支。特性开关的使用,在一定程度上让你的代码变得更脆弱。所以,特性开关的使用,是建立在良好的代码设计基础上。' g' Z" ]$ W/ o- `. ^ 为了弥补诸如特性开关这样针对某个特性开发的需要,而且现在软件开发中,越来越多的团队共同协作在一起完成某一个特性这样的场景,一种针对特性开发的分支模式就应运而生,这就是特性分支开发模式,最有代表性的就是 Git-Flow。 Git-Flow1 _7 X5 R o( |6 f6 `5 E0 |: y- J: e( u Git-Flow 是为了解决多个不同特性之间并行开发需要的一种工作方式。当开始一个特性的开发工作的时候,从主干上拉出一个特性分支,所有的关于该特性的开发工作都发生在这个特性分支上,当完成该特性的工作之后,再把特性分支合并回代码主路径上,并准备发布。 Git-Flow 有以下几种分支: ! g* Q2 }( k! i
特性开发过程中,需要针对该特性进行单独验证,当该特性并验证通过之后,merge 到一个叫做 develop 分支(大部分时间与 master 分支相近)的集成分支中,对整个软件进行验证。develop 分支永远保存都是最近的未发布版本,当 develop 分支的代码被验证可发布之后,单独从 develop 分支拉出 release 分支进行发布。 当拉出 release 分支进行发布过程中,如果发现缺陷,缺陷的修复发生在 release 分支上,所做的缺陷修改再持续同步到 develop 分支上。当 release 分支被发布完,其代码的最终版本会再次分别同步给 develop 分支和 master 主干上。我们可以发现, master 上永远保存的是可工作版本的基线。develop 分支保证的是开发集成中最新的版本。 Git-Flow 引入了一种叫做 hotfix 的分支,专门用于线上缺陷的修复。当缺陷修复完,再集成到 develop 分支,及同步到 master。其实,我们可以理解 hotfix 是一种特殊的 feature 分支,只是它的变更提交在集成到 develop 分支的同时需要同步到 master。 1 ~( F6 C& n, ]
; v( c& i0 a0 K8 z: a1 s+ |
9 y7 n+ {" I) x' K# a+ ?
, F) |* f! \+ o& H" N! d5 c# N! v
& A- b( G9 d- F# n3 @/ g: ^
; c5 J2 `8 G7 O
' j; s3 x' ]7 n9 c0 ^" g Hotfix 的流程如下:
, E. c. t/ @+ C8 y
( C* Z! w, \! e l9 ~
GitHub-Flow 在 GitHub-Flow 上,第一步就是没有 Git-Flow 中所介绍的 release 分支。对于 GitHub-Flow 来说,发布应该是持续地,当一个版本准备好,它就可以被部署。同样,在 hotfix 上的处理,GitHub-Flow 认为,hotfix 与那些小的特性修改没有任何区别,它的处理方式也应该与之相似。 在 GitHub-Flow 的整体流程是:+ X- A: g. K2 k. _
! X/ o J0 c6 B6 p
! O3 o9 \& D( J
$ a' }6 s; @5 ~/ Q- Y
+ Q# m+ f; \" F! m GitHub-Flow 相比 Git-Flow 来说,有个显而易见的好处——简单。另一个好处就是持续部署的要求,尽可能快速地发现 master 分支的问题,并能通过 rollback 等机制,快速恢复。将所有内容合到 master 分支中,并经常部署,意味着你可以最小化未发布的代码量,这也是精益开发和持续交付所倡导的最佳实践。部署原本是一件很繁琐的事情,但是因为要频繁做,我们就容易把这样一件事情做简单,以达到持续交付的目的。虽然 GitHub-Flow 简化了 Git-Flow 的分支模式,但是对于部署、环境、以及发布,该分支模式仍然存在许多未回答的问题,所以,我们希望通过 GitLab-Flow 来为这些问题提供更多的参考。 GitLab-Flow4 S' w5 U+ N! _" W* s# r GitLab-Flow 相比于 GitHub-Flow 来说,在开发侧的区别不大,只是将 pull request 改成了 merge request,而 merge request 的用法与 pull request 类似,都可以做为代码评审、获取反馈意见的一种沟通方式。! N' ] @& a" U9 W# ?; u) G: j 最大的区别体现在发布侧,即引入了对应生产环境的 production 分支和对应预发环境的 pre-production 分支(如果有预发环境的话)。这样,master 分支反映的是部署在集成环境上的代码,pre-production 分支反映的是部署在预发环境的代码,production 分支反映的最新部署在生产环境的代码。 当一个特性开发完成,提交 merge request,将特性开发的代码合并到 master,并部署到集成环境进行验证;当验证通过之后,提交 merge reqeust,合并 master 到 pre-production 分支,并部署到预发环境,进行预发环境上验证;当预发环境验证成功之后,再提交 merge request,将 pre-production 分支上的代码合并到 production 分支上。 5 q G! h3 q. l' q/ p
* }; G1 m4 E8 C. l& R# R 除了以上这种按环境,将主干发布向下游合并,并依次部署发布的过程。GitLab-Flow 同样支持不同版本的发布分支,即不同的版本会从 master 上拉出发布分支,不同的发布分支再走 pre-production 分支和 production 分支的方式进行发布。; k; F+ ?5 t2 x/ w: Z从上面的介绍中,我们发现,GitLab-Flow 更多是在发布侧做了更多的工作。同样 GitLab-Flow 因为跟 GitLab 工具强依赖,所以 GitLab-Flow 与 GitLab 中的 Issue 系统也有很好的集成,在其推荐的工作模式中,每次新建一个新的 feature 分支,都是从一个 issue 上发起的,即建立 issue 与 feature 开发分支之间的映射。& a. L9 M$ c" `/ }* J pros vs cons3 _: T, d: k; K6 f 所以,如果我们还是按照开发和发布的分支多寡来分类的话,以上这些分支模式分别属于:
4 e; W- I, Q+ R4 `5 y
& z) J! Q8 p* P) D5 w: w
根据团队自身和项目的特点来选择最适合的分支实践应该从哪些地方考量呢?. Y8 V7 l4 g; j2 d/ u 选择合适的实践 首先是项目的版本发布周期。如果发布周期较长,则 Git-Flow 是最好的选择。Git-Flow 可以很好地解决新功能开发、版本发布、生产系统维护等问题;如果发布周期较短,则 TBD 和 GitHub-Flow 都是不错的选择。GitHub-flow 的特色在于集成了 pull request 和代码审查。如果项目已经使用 GitHub,则 GitHub-Flow 是最佳的选择。GitHub-Flow 和 TBD 对持续集成和自动化测试等基础设施有比较高的要求。如果相关的基础设施不完善,则不建议使用。. e2 O2 b* ]) R
. Q; f& ?0 W+ B# u; x# w' C
- E8 t- I' s* Y$ i% g4 y! ^ 如果发现,现有主流的分支模式都无法满足你的要求,那么,我们可以定义自己的分支模式,如我们有个团队是基于主干开发的,于是定义了春夏秋冬分支模式,春天用“春分支”,夏天用“夏分支”......,我个人就蛮喜欢的,原因有二,一是做到了主干开发,持续发布,二是名字起得很有意思,开发工作一定要有乐趣,不是么? |
微信公众号
手机版