本文介绍几种常见的workflow,包括经典但繁琐的gitflow、简单而敏捷的github flow、相对折中的gitlab flow,并简单介绍特性分支开发模式主干开发模式的适用场景和优劣。

特性分支开发模式

软件项目的管理很大程度要依赖分支,当前最主流的分支策略是特性分支开发模式(Feature Branch Development)。特性分支开发模式是指为一个或多个特定的需求/缺陷/任务,从某个分支上拉出特性分支(branch),在该分支上完成相应的开发后,再把它合并(merge)回原分支的开发模式。这种模式是对分支最朴素的应用方式,下面要提到的几种工作流都是基于特性分支开发模式。

gitflow

gitflow最早是Vincent Driessen在其博客https://nvie.com/posts/a-successful-git-branching-model上提出的一套工作流,示意图如下:

可以看出gitflow是一种非常复杂的工作流,需要长期维护dev和master两个分支,还有feature、release、hotfix等其它分支,可以根据不同场景、不同需求提供完备的分支组合,基本能适应各类团队开发场景,所以一度非常流行。但是随着普及范围扩大,大家也渐渐发现gitflow的一些弊端:尽管每个分支都有自己的职责,但是各种组合切换非常复杂,上手成本和管理成本都非常高;feature 分支生命周期很长,合并时容易产生冲突(这是特性分支开发模式的缺陷);分支数量过多,在每个分支都需要部署测试环境的情况下需要占用大量资源。尽管如此,这也不妨碍我们从gitflow学习它的思想汲取精华,gitflow整体透露着一种严谨的学院风,feature分支用来开发特性,hotfix分支用于修复bug,release分支用于版本发布,每个分支各司其职,它的每个局部设计都很清晰和”正确”,甚至过于正确,但是也因此导致了整体复杂的开发流程,并牺牲了灵活性。

作者本人2020年也在原博客中补充到:长时间以来很多人将gitflow视为dogma(教条)和panacea(灵丹妙药),但这十几年来web应用、移动应用、游戏应用等大量新兴软件快速崛起,对敏捷开发和持续交付提出了更高的要求,和传统的商业软件开发需求完全不同。在这样的新时代背景下,切忌不懂变通死搬硬套,正确的方式是根据项目类型、开发阶段、运营周期灵活制定和调整项目工作流,没有最万能的工作流,只有最适合项目的工作流。

github flow

github flow是github提出的一种轻量级工作流,对比gitflow去掉了大部分分支,只长期维护一个master分支,任何需要的修改都通过创建future分支(或者使用fork)实现,在完成修改并通过测试后就可以向master分支创建一个拉取请求(PR),等待CR后即可合并到master,同时触发CI立刻部署,发布工作将直接在master分支上进行。

github工作流推崇小步快走、快速迭代,是一种很敏捷的工作流,适合小规模团队或开源项目使用。

gitlab flow

gitlab flow是gitlab提出的一种工作流,也是一种gitflow的简化版本,示意图如下:

gitlab flow和github flow最主要的区别是多了环境分支pre-production(预发分支)和production(生产分支),其它基本相同。因为github flow假设每次合并功能分支时部署到生产环境,但很多时候这无法实现,如需要应用商店审核的场景,此时production分支的作用就是反映已部署代码,gitlab在其文档https://docs.gitlab.cn/14.0/ee/topics/gitlab_flow.htmlhttps://docs.gitlab.com/ee/topics/gitlab_flow.html中对gitlab工作流有详细的解释。

主干开发模式

前面提到基于特性分支开发模式的各种workflow有一个缺陷是很容易产生长期存在的特性分支,导致合并时常常产生冲突,另一种模型主干开发模式(Trunk Based Development)即可解决这个问题:

在主干开发模式下,团队成员需要更频繁地将较小的更改合并到主代码库中,并处理主干副本,而不是处理长期存在的功能分支,因为working copy和主干的差异不大,所以可以大大减少合并冲突。主干开发模式在当下是敏捷开发团队中越来越流行的devops实践。

Feature Toggle(特性开关):将新特性包装在可以远程开启或关闭的代码中,可以在实现主干开发模式的同时降低引入风险。因为主干开发模式涉及在生产环境中的单个分支中工作,所以特性开关提供了一种以受控方式将新特性和更改引入代码的方法,并在发现任何错误时快速关闭它们。特性开关也可用于向项目用户群的一小部分缓慢推出功能,而不是进行一次大规模发布,这有助于限制任何潜在错误代码的​影响范围。

乍一看主干开发模式多少有点返璞归真,软件开发早期阶段正是使用这种相对”粗放”的管理模式,现如今使用这种模式一方面需要团队成员的个人能力和协作能力比较强,另一方面需要完善的持续集成能力的基础平台,并不一定适合所有团队(尤其新团队),更适合团队代码风格成熟、devops建设完善的团队。因为一旦合入主干的代码质量出现问题,将会阻塞整个团队的进度,所以对团队代码质量要求较高,并需要有完善的CR机制和自动化测试能力,将问题代码尽可能在发布的前置环节发现并解决。目前谷歌和腾讯在内部都在大量使用主干开发模式。

版本发布分支的正确实践