跳转至

18 分支:是捷径还是“不归路”?

你好,我是黄俊彬。

前面我们做了组件化架构的重构,经过组件化,软件变得更加高内聚、低耦合,开发及维护的效率也更高了,但是组件化的架构又会引入新的复杂度。

举个例子,在重构前我们基于一个模块一次编译就出一个版本,而组件化架构需要我们同时维护更多的组件版本以及管理更多组件的集成,这就又增加了复杂度。

那么怎么来解决这个问题呢?在持续交付篇,我会带你系统学习分支管理、版本管理、制品管理以及流水线的设计等工程实践,通过自动化来管理增加的这部分复杂度,让组件化的架构能发挥更大的作用。

分支是我们日常进行开发一定会涉及到的工程实践,这节课我将为你讲解如何管理分支,带你熟悉分支的作用、常见的分支模型以及组件化架构分支策略。

分支作用

在版本控制与软件配置管理中,分支是从某个版本的代码或文件中建立复制版本,在分支后的两个版本里都可以独立做修改。

分支有什么作用呢?我先给你举几个研发过程中使用分支的常见场景。

  • 我们有几个功能需要同时在研发,为了互相不干扰,拉取各自的Feature分支进行开发。
  • 有多个线上发布版本需要同时维护,为了便于追溯,每个版本都会维护各自的Release分支。
  • 线上版本出现Bug,为了快速修复,基于发布分支拉取HotFix分支进行修复。
  • … …

结合这些场景,我们不难分析出,拉分支的主要目的是并行开发不同的功能,同时不让开发中的功能受到其他并行功能的影响。

分支让我们可以更加灵活地控制软件版本的发布,以及团队并行开发之间的协作。但是,很多团队往往会因为缺少分支的规范及有效的管理,出现大量的长期并行分支,这样就会影响开发效率。

分支管理不当,就会导致后面这些问题。

  • 由于存在大量的并行发布分支,当修复一个问题的时候,需要花费大量的时间在各个分支上进行代码同步。
  • bug修复了,但是没有及时同步到主干分支,导致提测的时候又出现相同的问题。
  • 拉了特性分支开发,由于时间比较久,代码差异越来越大,最后代码合并不回去。
  • ……

由此可见,分支给我们带来灵活性的同时,如果不能有效规范其的使用,最后反而会降低团队的研发效率。

分支模型

那么如何来解决分支管理混乱的问题呢?一个有效的方式就是在团队内部采用统一的分支模型,规范分支的拉取及合并。

我们这就来学习3种常用的分支模型,它们分别是GitFlow模型、短特性分支模式以及单主干模型。讲解过程中,我还会带你了解这些模型的设计思想,方便你做选型参考。

GitFlow模型

首先我们先来看看GitFlow这种分支模型。GitFlow设计之初,主要是为了解决使用Git时,Git提交记录杂乱无章的情况。不难想象,每个人都随心所欲去提交自己的代码,项目很快就会变得难以协调和维护。

后面是GitFlow分支模型图。

我们从上图可以看出,开发人员主要都是基于Develop分支来开发的。开发新的特性时,首先需要基于Develop分支拉取Feature分支,然后基于这个Feature分支实现特性开发,完成后合并入Develop分支。

当有版本需要发布时,就要基于Develop分支拉起对应的Release分支来做版本测试,验证成功后就会将代码合并到Master分支中,并打上Tag标记。如果版本在线上运行时出现问题,会基于Release分支拉取Hotfixes分支并修复问题,修复完再将修改合并到主干和Develop分支中。

GitFlow分支模型的特点是开发各自在特性分支上互不干扰地开发,特性分支可以长期存在,甚至跨越多个发布周期。但是GitFlow分支也有一些问题,比如日常提交分布在各条特性分支,无法及时集成和联调;特性分支生命周期太长,冲突风险增加。

短特性分支模型

那么如何来优化GitFlow长期特性分支带来的问题呢?这就要说到第二种常用的分支模型——短特性分支模型。

短特性分支模型指的是所有的开发者都在主干上进行协作开发。在这种模型下,为了保持灵活性,是不允许新建任何长期存在的开发分支的,但可以使用短的特性分支来持续集成。后面是短特性分支模型图。


短特性分支模型的特点是使用周期非常短的特性分支,一般情况下,短特性分支的生命周期一般在3天左右,不超过5天,所有特性都会合并到主干。另外,当线上版本需要修复bug时,会基于Release分支的Tag来修复bug,修复记录需要同时合并到主干分支。

短特性分支模型需要配合其他敏捷实践一起使用,团队要提前规划固定节奏的发布计划,并且要将特性拆分成可以独立交付的小故事(任务)。为了保证代码质量,则需要完善的代码审核和持续交付的流水线,且在合入主干前要先验证所提交代码的质量,通过流水线保证主干随时可发布(至少是测试版本)。

单主干分支模型

短特性分支已经可以很好帮助我们实现版本持续集成,但如果你需要更加频繁地集成发布。可以参考第三种分支模型——单主干分支模型。

单主干分支模型与短特性分支模型类似,关键的区别是单主干没有短的特性分支,有且只有1个开发分支,即主干分支,所有改动都发生在主干分支。后面是单主干分支模型图。

单主干的挑战相比短特性分支模型更大,由于所有的特性都是直接合并到主干分支,所以对于代码合入质量、需求规划要求更高。另外,在架构上需要支持使用抽象的“分支”或特性开关来屏蔽特性,从而保证主干上的功能能够灵活地配合规划发布相应的版本。

不过,单主干也有它的优点,由于没有临时开发分支,所有特性都能及时集成。而且其模型简单,分支少,开发人员的切换成本低,所以单主干模式也是最符合持续集成的要求。

Sharing分支模型设计

最后我们来看看组件化架构的分支模型要如何设计。通常情况下,组件化的架构一般分为2个部分,第一个部分是独立维护迭代的组件,另外一个部分是集成发布组件的基座。我们分别来看看这2种类型的分支模型。

因为组件会持续不断地演进新的功能,所以常常会出现一个版本内多个小特性同时开发的情况。所以建议组件分支模型可以考虑使用短特性分支模型

在实践过程中,我们需要将需求拆分为各个小的特性或者任务,并且通过质量门禁来保障合入主干的代码质量。并且为了保护主干分支的质量,我们可以将主干分支设置为保护分支,所有合并入主干分支的代码需要提交MR或者PR,经过人工代码检视后,再合入主干分支。

对于集成的基座来说,通常代码提交只为配置需要发布的组件,然后集成发布组件。所以对于集成基座的分支模型,可以考虑使用单主干分支模型。但在实践过程中,我们仍然可以利用版本管理工具的MR或者PR来人工Reivew,但此时的临时分支仅仅只是为了做代码监视而已。

确定好产品的分支模型非常重要,因为后续的持续基础流水线都会基于分支来触发构建,我们可以根据不同的分支类型,针对性地设计流水线环节与质量门禁,为高效、高质量地发布软件版本保驾护航。

总结

今天我们一起学习了分支的作用、常见的分支模型以及组件化架构分支策略。

分支的灵活性像是一条捷径,让我们可以在研发过程中更方便地去做功能组合以及控制版本发布。但是如果缺少规范及约束,大量长期的分支会大大增加我们后期合并代码的工作量,所以“美酒虽好,但不能贪杯”。

因为对于分支来说,长期分支在本质上和持续集成背道而驰!分支一旦拉出,就意味着有分叉,没有及时集成代码。分叉的时间拖得越久,那么代码的差异可能就越大,最后合并的成本可能就越高。如果没有重视及做好分支规范,可能会导致需要花费大量的时间及人力在做代码合并的工作。

之后我们一起了解了3种常用的分支模型,GitFlow、短特性分支以及单主干,你可以在实践中根据自己的产品以及团队规模来选择合适的分支模型。

对于组件化架构的分支策略来说,组件分支模型可以参考使用短特性分支模式,集成基座的分支模型可以参考使用单主干分支模型。但是注意不管选择何种模型,我们仍然建议需要做好分支的规范以及管理,避免存在大量的长期并行分支。

最后,如果团队短时间内无法统一分支模型,为了持续集成我们还可以在分支管理方面,做哪些努力呢?我帮你总结了实践过程中拉取分支的六个要点。

  1. 尽量少拉长期分支。
  2. 尽量晚拉分支。
  3. 分支尽早合并或删除。
  4. 分支活跃期间要频繁同步。
  5. 分支从哪里拉出来,就合并回哪里。
  6. 主干分支必须保持随时可发布。

下节课,我们将继续学习另外2个核心的工程管理实践,组件仓库管理以及二进制版本管理,一起学习如何从物理上规范组件的依赖以及集成,敬请期待。

思考题

感谢你学完了今天的内容,今天的思考题是这样的:你能画出你现在产品的分支模型吗?你觉得有什么可以优化的地方吗?

欢迎你在留言区与我交流讨论,也欢迎你把它分享给你的同事或朋友,我们一起来高效、高质量交付软件!

精选留言(2)
  • wh 👍(0) 💬(2)

    请教老师个问题: 在做模块分层的时候,会把网络层放到独立的Module中,那么Bean要不要也放到这个Module中;网络层包括哪些内容?

    2023-03-23

  • peter 👍(0) 💬(1)

    请教老师几个问题: Q1:短特性分支模型怎么保证短时间?为什么GitFlow不能保证短时间? Q2:本文的模型,都是针对git的吗?如果用其他的版本管理工具,也适用吗? Q3:安卓的屏幕适配,有框架吗?有的话,用框架好还是不用框架好?

    2023-03-22