Git的分支就如同河流一般,从一个发源地开始,向下游流去,时而汇聚,时而分叉,分支形成的模型可以是树状的,可以是网状的。由于Git的分支特性灵活强大,许多人在刚开始使用的时候比较迷茫,什么时候该建分支,什么时候该删分支,什么时候需要分叉,什么时候需要汇聚。
0x01 分支管理认知
分支分类
按照职责分
每个分支都带着职责出生,没有职责的分支,就没有存在的必要
- master分支:用于归档,打tag
- release分支:用于迭代发布准备的汇聚分支
- feature分支:用户需求特性的开发
- hotfix 分支:用与bug修复
按照生命周期分
每个分支都有其生命周期,生于职责开始,猝于职责结束。
- 长期分支:长期分支一般为汇聚归,归档分支,例如master,develop分支
- 短期分支:分支职责只在某一个时期内有效,用完后生命周期结束,例如hot fix 分支和 feature 分支
分支管理场景
根据上面对分支的归类,基于Git的workflow往往由一个或者两个长期分支和若干短期分支参与协调完成;分支宜少不一多,协同步骤也要宜少不宜多,减少分支管理的复杂度,所以根据自身团队的开发模式灵活调整,能不拉新分支就不拉新分支,能不汇聚就不汇聚,但是要保证分支职责的纯净。下面举例说明:
一个开发者
- 正常开发和发布可以直接在master分支操作,发布后及时归档打tag。
- 当线上发生bug的时候,可以从归档tag拉出一个hotfix分支,hotfix 分支上线后,合并到master分支
多个开发者
例如公司开发团队多个开发者,多个特性同时存在的时候,由于存在需要汇聚发布,或者汇聚后又有需求需要中途终止发布的情况,这时需要一些简单的workflow,当然如果非常有默契,大家对Git的理念烂熟于心,一切的workflow 都是浮云,无招胜有招。建议workflow 如下图: 由一个长期分支加若干短期分支组成
- 长期分支master分支,承担仓库的归档管理
- 短期分支release分支,承担迭代发布过程中特性分支的汇聚
- 若干的短期feat分支,承担迭代开发过程中的开发管理
当汇聚发生后,如果feat-a,feat-b 有bug,那么修bug应该在哪个分支修呢?建议如下图操作: 每个特性的bug都在原有的特性分支修复,修复后合并到release分支;这样操作看似麻烦,但是有个好处就是,如果feat-a,或者feat-b 其中一个特性遇到特殊原因取消发布了,这时候拉出的release分支可以废弃掉,重新拉出一个release分支进行汇聚发布,或者特性直接合并到master发布,当然建议新拉一个release分支作为汇聚分支合并某一个特性分支后发布,如下图: release-1 因为客观原因废弃调,然后feat分支错开了,独立发布。独立发布情况下一定要release-2 和release-3 吗?不是必要的,这个需要根据CI规则调整。
0x02 常见的Git Workflow
Git flow
Git flow 由两个长期分支和若干短期分支组成,每个分支职责单一,维护较为麻烦:
- master分支,长期分支,用于归档
- develop分支,长期分支,用于开发过程中的汇聚
- featurea分支,短期分支,承担开发阶段的特性记录
- hotfix分支,短期分支,用于线上bug的紧急修复和发布
- release分支,短期分支,用于发布阶段的代码维护
从上图可以看出,master分支只承担了归档职责,develop承担了若干短期分支的汇聚管理职责。分支分叉和合并情况可以看出;develop分支和hotfix分支分叉于master分支,release分支,feature分支分叉于develop分支;所有的短期分支都需要汇聚到develop分支,release分支在发布成功后合并到master分支和develop分支。Git flow 对于有严格发布时间表的项目来说比较适用,而且对于团队的管理要求比较严格,因为团队必须严格执行Git flow,不然带来的是混乱。
Github flow
Github flow 规则:任何进入master分支的代码,都是可以发布的,所以基于master分支,拉出任何类型的分支,不能影响master分支。GitHub flow只有一个长期分支若干短期分支组成。 通过GitHub flow guide 可以了解到其步骤为:
- 基于master拉出任何类型的短期分支
- 短期分支完成开发阶段的commit
- 打开一个 pull request(合并请求)
- 代码review
- 完成部署
- 合并到master 上文描述的workflow 模型,也是基于GitHub flow的变种。上文提到的需求错开发布,不拉release分支情况下,就和GitHub flow一致了。相较于Git flow,GitHub flow简单轻量,分支少,管理压力小。
Trunk-Based flow
TBD(trunk-base development) 基于主干分支的workflow,在Git中即所有的开发人员代码开发都在master分支进行,当到需求处于可发布状态的时候,拉出release分支,进行测试发布。如果有bug发现,基于master分支修改,再将对bug的修复commit 挑选出来,合并到release分支,这里使用了Git 的cherry-pick特性。过程如下图所示: TBD 模型下,只有一个长期协作用的主干分支,和release短期分支,减少了分支管理和代码冲突带来的工作量。
小结
Git flow: 稳重,规则多,适合发布时间严格,节奏慢的团队。
GitHub flow:轻量灵活,适合发布节奏较快的团队。
Trunk-Based:减轻了代码合并和分支管理带来的流程复杂度。
不必削足适履,还是要根据团队自身的情况来选择合适的workflow。