
多年前,在给一个团队辅导时候,有人问为什么需要代码分支?这让我多少有点诧异。 业界有诸如TBD、GitHub Flow、git-flow , gitlab-flow以及 AoneFlow等分支管理策略, 它们都是在具体的实践场景下演化而来的。
本文将从“为什么需要代码分支”开始,有简入深,探究分支的本质,设计适合你团队的分支。
分支开发往小了说,是版本管理的一种方式。往大了说,它与产品发布、研发团队间协作、集成方式,服务器测试环境管理等密切有关。
首先记住一句话,开分支是为了解决“稳定”和“快速发布”的矛盾,既要现有功能的“稳定”又要“快速”发布新功能**。为了保证现有功能的稳定,那么就要“隔离”,让“现有的”和“新开发-不稳定的”保持隔离。
但是“现有的”和“新开发的”最终要一起发布,于此同时,多个“新开发的”特性有会容易引起冲突。
一般把Trunk(Master)称之为主干,Branch称之为分支,但是Trunk永远只有一个。对应线上的版本,我们用称之为发布分支的Release来管理。Release分支上永远是稳定版本。
正是这中间两步的差异,造就了两个开发模式之间的天壤之别,而彼此的优缺点也大不相同。

画板
该分支模型衍生出来的典型示例如下,就是我们熟悉的git-flow分支模型(多分支并行开发,单一发布分支)。

适用场景:网站、SAAS服务、APP 版本是一直滚动迭代的。
团队人数的增多,可能要处理好:
实际使用中,为了方便测试与发布准备,单一发布分支中间会增加几个分支用作缓冲,例如先使用一个test分支用作合并feature并先行测试验证。测试验证过后,再合并到staging分支做发布准备。发布实际完成以后再合入main。
本来该模型主要用于saas系统的版本迭代,不过在实践中,看到很多非saas产品团队特别习惯使用这种,主要原因就是因为开分支做“缓冲”用,来源于对自己产品质量的不自信,怕污染主干master。

画板

画板
如下图,展示了单一分支开发,发布后创建分支的典型示例。

适用场景:2B类商业软件,客户多,既要保证主线演进,也要兼顾交付版本维护
软件发布后,开发团队需要处理的两项主要工作
注意:当一项改动(例如一个缺陷的修复)需要应用到多个已发布的分支时,在某个分支修复后,需要将对应的一个或多个提交合并到其他受影响的分支。可以使用代码库的指令(例如 git cherry-pick)来完成此操作。有时,如果代码差异较大,可能需要人工介入进行手动修复。

画板
如下图,展示了一个开源项目的分支图,接近一条直线。在项目初期以及开源项目比较常见(省去了维护分支的成本),仅使用一个分支协作,提交代码,对特别版本进行标记TAG。
该模型是业界比较推崇的,但依赖基础设施和自动化的保障,以及协作成员的代码质量,在实际的研发活动中,受制于团队水平以及交付集成限制,较少见到。

针对上面的四种模型,个人更推崇后两种,过多的分支和不够完整的少频次集成,并不是好事。这里重点再分析下后两种。
如下图,从代码的路径我们可以看到多个开发人员的代码的汇聚点在Trunk上,这就是主干开发第一个显著的特点,即所有开发人员的代码都是基于同一套代码进行开发。开发人员每天都在这个主干上签入签出他们的代码,不断地集成,测试和修复,直到计划的发布的功能被实现的时候,再从这个版本打一个Tag,然后拉一个测试分支发布到系统测试环境。系统测试人员对测试分支进行系统测试。而同时开发人员则继续在主干上开发新的功能。系统测试环境发现的缺陷,会在系统测试分支上被修复,修复后立刻同步到Trunk上。经过系统测试的版本接下来会发布到生产环境。而此时开发人员可能正在准备第二个版本的系统测试交付。

主干开发-分支发布
主干开发模式极大消除了系统集成风险,让原本痛苦的系统集成,在开发阶段的时候就无时无刻的发生。这种模式把敏捷的持续集成实践方法发挥到了极致。这就使得系统的潜在可交付产品(Potential Shippable Product)的成功率大大被提高了。
与Scrum中的迭代潜在可交付产品略有不同的是,Scrum的迭代交付是在迭代内完整功能的交付,如果不能在本迭代做完的功能,则建议拆分地端到端更为细小或者放入下一个迭代来完成。直到可交付的功能可以满足一定业务需要时,才进行系统测试和发布。当然在迭代过程中进行系统测试也不是坏事,只要有自动化或者人力保障(关于迭代内回归测试对于刚转型的scrum团队来说,永远是抹不掉的痛)。因此Scrum的发布周期和迭代长度往往是1:1或者1:N的关系。

主干开发-主干发布
回到主干开发,它将要交付的版本并不包含所有完整,开发人员需要通过功能开关来屏蔽不希望用户看到的功能。只有那些实现了完整业务的功能才会被展现在用户面前。这样做看上去很不“安全“,但是却解决了功能不能拆分或不能组装而无法完整业务发布、不能发布的问题。
正因为这样,主干开就发变得“准”时可发布。它可选择的发布窗口期可以不再是迭代的倍数,而是在迭代内也可以,甚至有团队做到每天一发布
主干开发是指所有开发者在同一主干上进行代码的提交与更新。这种方式在复杂环境中能提前发现并解决问题,但不太适合高度定制化的产品
对于需要定制化的产品,可以将其分为核心功能和定制功能两部分。核心功能适合使用主干开发;而定制功能(如更改产品首页Logo)则可以通过配置来实现,避免创建新的分支,从而保持版本的一致性。随着产品的发展,定制需求增加时,产品经理需考虑是否减少定制项或将一些定制特性整合为核心功能。
在尝试主干开发前,团队需考虑是否真正需要它以及它能否解决当前面临的问题。同时,还需确保满足特定的前提条件,并在实施过程中注意以下几点:
一句话,“主干开发-主干发布”更加适合互联网产品、单一产品的主流开发模式;“主干开发-分支发布”没有前者那么激进,对于多客户多版本的商业软件相对比较合适。但是,两者都对主干分支的质量提出了更高的要求。
正如开头说的,分支模型看似是个很小的事情,实际研发过程中,和周边很多因素有关系(如下图)。
忘掉那些主流的分支模型,只要掌握了上述四种基本的分支模型,吃透里面的内涵,就可以定义适合团队协作交付的好的分支策略。
最后,让AI编了一个顺口溜,结束本次的分享。

画板