写点什么

阿里巴巴如何管理代码分支?

  • 2019-08-14
  • 本文字数:5324 字

    阅读完需:约 17 分钟

阿里巴巴如何管理代码分支?


阿里内部,流行着许多有意思的工程实践。有些实践通过工具和流程嵌在集团的大环境里,外界不容易复制,有些实践则是流露在大家的日常习惯里,被默默的遵守。比如分支管理这件事,其实属于工具和习惯各占一半,并且颇有阿里特色的成分,适合作为一个例子。阿里有很多的研发团队,不同事业部使用的发布流程、分支策略并非整齐划一,但总体上看是比较规整的。其中有一种主流的发布模式以及对应的分支使用方式,称为“AoneFlow”。这套工作模式思路独特,在阿里以外的地方并不多见。本文围绕这些实践,聊一聊分支管理的话题。

细数分支模式

说到分支管理模式,我们最耳熟能详的莫过于 TrunkBasedGitFlow


TrunkBased 模式 是持续集成思想所崇尚的工作方式,它由单个主干分支和许多发布分支组成,每个发布分支在特定版本的提交点上从主干创建出来,用来进行上线部署和 Hotfix。在 TrunkBased 模式中,没有显性的特性分支。当然实际上 Git 的分布式特征天生允许每个人有本地分支,TrunkBased 也并非排斥短期的特性分支存在,只不过在说这种模式的时候,大家通常都不会明确强调它罢了。


虽然近年来有许多不错的案例,但 TrunkBased 模式并没有一统天下。它的缺点比较明显,太多的团队同时工作在主干上,到发布的时候就可能出现灾难(尤其是多版本并行开发的情况)。弥补的措施是 FeatureToggle 以及频繁的集成和足够的测试覆盖,这对开发团队的能力提出了比较高的要求。目前 TrunkBased 模式主要用在不需要同时维护多个历史版本的 SaaS 型项目,特别是经过微服务改造的各种小型服务上。


TrunkBased 模式有两种常见演进版本。OneFlow 模式 参考了 TrunkBased 的许多思想,对操作流程做了更严格的定义,增加了 Hotfix 分支等内容。多主干模式(通常是双主干,固定的开发分支和固定的发布分支),算是 TrunkBased 采用固定发布分支的特例,在 提升团队的微服务落地能力 这篇文章里介绍过,不再赘述。


GitFlow 模式是若干模式的集大成者,包含一个主干分支、一个开发分支、许多的特性分支、许多的发布分支和 Hotfix 分支,以及许多繁琐的合并规则。它有一个 Git 插件,不过早就没人维护了。由于对每个阶段的每项操作定义十分明确,它曾经是很多重视流程的企业眼里的香馍馍。但它使用起来并不是很容易,大量的合并冲突和对集成测试不友好也是它被诟病最多的地方。


对,还有 GithubFlow 模式,不过这种策略无非是在 TrunkBased 的基础上,增加了个人仓库和 Pull Request 合并代码的操作,与在同一个仓库里增加个人分支的做法类似,从实用的意义来说,它更合适分布式团队。GithubFlow 也有演进版本,例如强调了多环境部署和将仓库或分支与环境关联的 GitlabFlow 模式。


要么简单粗暴如 TrunkBased,要么繁琐复杂如 GitFlow。难到真没有其他选择了吗?

另辟蹊径的 AoneFlow

在 AoneFlow 上你能看到许多其他分支模式的影子。它基本上兼顾了 TrunkBased 的“易于持续集成”和 GitFlow 的“易于管理需求”特点,同时规避掉 GitFlow 的那些繁文缛节。


看一下具体套路。AoneFlow 只使用三种分支类型:主干分支、特性分支、发布分支,以及三条基本规则。


规则一,开始工作前,从主干创建特性分支。


AoneFlow 的特性分支基本借鉴 GitFlow,没有什么特别之处。每当开始一件新的工作项(比如新的功能或是待解决的问题)的时候,从代表最新已发布版本的主干上创建一个通常以<span>feature/</span>前缀命名的特性分支,然后在这个分支上提交代码修改。也就是说,每个工作项(可以是一个人完成,或是多个人协作完成)对应一个特性分支,所有的修改都不允许直接提交到主干。



规则二,通过合并特性分支,形成发布分支。


AoneFlow 的发布分支设计十分巧妙,可谓整个体系的精髓。GitFlow 先将已经完成的特性分支合并回公共主线(即开发分支),然后从公共主线拉出发布分支。TrunkBased 同样是等所有需要的特性都在主干分支上开发完成,然后从主干分支的特定位置拉出发布分支。而 AoneFlow 的思路是,从主干上拉出一条新分支,将所有本次要集成或发布的特性分支依次合并过去,从而得到发布分支。发布分支通常以<span>release/</span>前缀命名。



这条规则很简单,不过实际的玩法就相当丰富了。


首先,发布分支的用途可以很灵活。基础玩法是将每条发布分支与具体的环境相对应,比如<span>release/test</span>分支对应部署测试环境,<span>release/prod</span>分支对应线上正式环境等等,并与流水线工具相结合,串联各个环境上的代码质量扫描和自动化测试关卡,将产出的部署包直接发布到相应环境上。进阶点的玩法是将一个发布分支对应多个环境,比如把灰度发布和正式发布串在一起,中间加上人工验收的步骤。高级的玩法呢,要是按迭代计划来关联特性分支,创建出以迭代演进的固定发布分支,再把一系列环境都串在这个发布分支的流水线上,就有点经典持续集成流水线的味道了。再或者做一个将所有特性分支都关联在一起的发布分支,专门用于对所有提交做集成测试,就玩出了 TrunkBased 的效果。当然,这些花哨的高级玩法是我臆想的,阿里的发布分支一般都还是比较中规中矩。


其次,发布分支的特性组成是动态的,调整起来特别容易。在一些市场瞬息万变的互联网企业,以及采用“敏捷运作”的乙方企业经常会遇到这种情况,已经完成就等待上线的需求,随时可能由于市场策略调整或者甲方的一个临时决定,其中某个功能忽然要求延迟发布或者干脆不要了。再或者是某个特性在上线前发现存在严重的开发问题,需要排除。按往常的做法,这时候就要来手工“剔代码”了,将已经合并到开发分支或者主干分支的相关提交一个个剔除出去,做过的同学都知道很麻烦。在 AoneFlow 的模式下,重建发布分支只是分分钟的事,将原本的发布分支删掉,从主干拉出新的同名发布分支,再把需要保留的各特性分支合并过来就搞定。这一系列动作能够在很大程度上实现自动化,而且不会在仓库留下一堆剔除代码的记录,干净无污染。


此外,发布分支之间是松耦合的,这样就可以有多个集成环境分别进行不同的特性组合的集成测试,也能方便的管理各个特性进入到不同环境上部署的时机。松耦合并不代表没有相关性,由于测试环境、集成环境、预发布环境、灰度环境和线上正式环境等发布流程通常是顺序进行的,在流程上可以要求只有通过前一环境验证的特性,才能传递到下一个环境做部署,形成漏斗形的特性发布流。阿里有统一平台来自动化完成特性组合在发布分支间的迁移,在下面讲工具的部分里会再介绍。


规则三,发布到线上正式环境后,合并相应的发布分支到主干,在主干添加标签,同时删除该发布分支关联的特性分支。


当一条发布分支上的流水线完成了一次线上正式环境的部署,就意味着相应的功能真正的发布了,此时应该将这条发布分支合并到主干。为了避免在代码仓库里堆积大量历史上的特性分支,还应该清理掉已经上线部分特性分支。与 GitFlow 相似,主干分支上的最新版本始终与线上版本一致,如果要回溯历史版本,只需在主干分支上找到相应的版本标签即可。



除了基本规则,还有一些实际操作中不成文的技巧。比如上线后的 Hotfix,正常的处理方法应该是,创建一条新的发布分支,对应线上环境(相当于 Hotfix 分支),同时为这个分支创建临时流水线,以保障必要的发布前检查和冒烟测试能够自动执行。但其实还有一种简便方法是,将线上正式环境对应的发布分支上关联的特性分支全部清退掉,在这个发布分支上直接进行修改,改完利用现成的流水线自动发布。如果非得修一个历史版本的 Bug 怎么办呢?那就老老实实的在主干分支找到版本标签位置,然后从那个位置创建 Hotfix 分支吧,不过由于阿里的产品大多是线上 SaaS 业务,这样的场景并不多见。


正是这些简单的规则,组成了 AoneFlow 独树一帜的核心套路。


AoneFlow 中每一个看似简单的步骤都并非凭空臆造,而是经历大量产品团队反复磨砺后积累下来的经验。接下来,我会说说 AoneFlow 的技术门槛以及阿里内部的应对之道。

AoneFlow 的体验优化

谙熟武侠之道的人都懂得,掌握一个门派的看家武艺,除了要会招式,还得有深厚的内功和趁手的兵器。否则拿了辟邪剑谱,也只能望谱兴叹。


阿里团队的内功和兵器,实际上是良好的代码习惯和齐全的配套工具。


这里说的习惯,除了开发流程和代码分支的管理方式以外,还包括日常开发中的一些约定俗成的规约。阿里的许多开发规约是有“文献”记载的,主要收录在 《阿里巴巴 Java 开发手册》 里面。它的内容现在已经公开了,所以早就不算是秘密。


举一个具体的例子。在 AoneFlow 的流程中,每次重建发布分支的时候都会重新合并然后编译代码,产生新的部署包。然而,即使代码的内容是一样的,如果工程中依赖了一些会改变的第三方软件包,依然可能导致打包出的产品行为不完全一致。因此,在阿里的代码规约中就明确地指出了,用于线上发布的代码,不可以使用包含“SNAPSHOT 版本”(即未正式发布版本)的依赖包,从而确保每次构建出的产物都是一致的。类似这样的细节还有很多,好的开发习惯是确保软件质量的必要前提。


工具可以使得团队协作更加平滑。虽然只要弄懂原理,AoneFlow 中每个分支创建、合并、更改步骤使用单纯的 Git 命令就能玩转。但其中的一些操作(比如为每个发布分支选出恰当的特性分支组合进行合并)手工执行极易出错,而且让团队的个人重复这些日常琐事的命令操作,并不是令人愉悦的事情。


在阿里内部,使用 AoneFlow 流程的团队基本上不用自己运行 Git 来处理分支的事情,而是由阿里巴巴集团内部名叫 Aone 的协同研发平台(以下简称平台)接管。这个承担集团 80% 产品从需求和用户故事提出到部署上线完整研发流程的平台,内置了许多以服务组件的形式嵌入的研发提效工具,其中的发布组件为 AoneFlow 的用户体验添色不少。比较显著的辅助“功效”包括以下几个方面。


首先是整体流程的自动化。


由于是内部工具,平台的功能高度内聚。对于项目而言,从提出原始需求,将需求拆分为任务,然后根据任务在线创建特性分支,再聚合生成发布分支,同时根据模板自动创建测试环境,直到后期的运维保障都可以一站式的搞定。


这个流程已经远远超出了代码分支管理的范畴。但正是因为如此,平台对于 AoneFlow,向前做到了将特性分支和需求项关联起来,确保了特性分支的命名规范性;向后做到了将发布分支与部署行为关联起来,确保了各环境版本来源的可靠性。打通了端到端交付的任督二脉。


其次是发布分支的流水线。


作为一种流程自动化的手段,CI/CD 流水线是许多现代交付团队中常见的标配实践。在 AoneFlow 的代码生命周期里涉及许多分支,当这些分支被创建或更新时,往往需要伴随其他的一系列行为。流水线能够将这些日常开发过程中的代码分支与其所表达的深层意图(比如提交代码即进行集成测试)联系起来。特别是发布分支,AoneFlow 的每个发布分支通常关联具体的部署环境,当有新代码合并进分支时,就应该及时对代码进行检查和部署。


理想情况下,每条不同的分支都应该有与其作用相匹配的一条流水线来为它服务。AoneFlow 的发布分支是相对固定的,因此相比 GitFlow 更易于进行持续集成。理论上任何流水线工具都能够配合 AoneFlow 使用,不过,阿里的统一平台提供流水线对代码评审、安全检查、在线部署等功能的整合,还是为 AoneFlow 在内部团队的使用优化增色不少。


还有一项很有用的辅助是分支关联的管理。


特性分支与发布分支的关联关系维护是一个 AoneFlow 特有的问题。记住每个发布分支分别来自哪些特性分支对于需要基于现有特性组合进行改变的时候十分有意义。比如当需要将某个特性从特定发布分支退出时,通常会将除了该特性以外的其他特性所在分支进行一次合并,以替换原有的发布分支。人为的记录这些信息并不轻松,要是通过平台进行展示和辅助就会方便许多。


当某些功能组合在一个低级别的发布环境(如集成测试环境)验证完成后,我们希望将它的内容直接迁移到高级别的环境(如预发布环境)对应的发布分支上。这样可以确保线上的版本一定是经过预发验证的,预发的版本一定是经过集成验证的,以此类推,使得各个发布分支形成串联。同样的,使用普通的 Git 命令就能实现这个操作,只不过用可视化工具会让流程更加直观。


除此以外,平台提供代码仓库各个分支状况的统一展示,包括分支所对应部署环境的机器信息、操作记录等全都一览无余。正是这些“高附加值”的辅助,使得 AoneFlow 得以扬长避短,成为阿里团队支撑复杂项目首选的利器。


不久前,2017 年 12 月 20 日云栖大会,阿里协同研发平台的团队刚刚在阿里云上 发布了一款公开版的研发效能产品:云效。相比集团内部平台,目前公开的 云效 还只是初级版本,不过值得庆幸的是,它 对 AoneFlow 的支持 已经比较完备,好奇之士可自行前往探索。


地址:https://yq.aliyun.com/articles/307586

写在最后

代码分支模式的选择并没有绝对的正确和错误之分,关键是与项目的规模和发布节奏相匹配。阿里协同研发平台在经过众多实践历练后,总结出了一套独创的分支管理方法,通过兼备灵活高效与简单实用的流程,保障阿里旗下众多产品的交付。当你还在犹豫于琳琅满目的分支模式,既舍不得 GitFlow 的并行特性开发,又放不下 TrunkBased 的持续集成友好时,AoneFlow 也许是一个值得考虑的选择。

作者介绍

林帆(花名金戟),阿里巴巴研发效能事业部技术专家。


2019-08-14 14:5311702

评论 2 条评论

发布
用户头像
发布和测试是2个分支,岂不是有风险吗
2020-06-30 17:41
回复
用户头像
大厂可以自己造轮子,小公司还是多用开源解决方案吧
2019-08-15 09:21
回复
没有更多了
  • Java 开发必备 Git 分支开发:规范指南及完全学会 Git 的 24 堂课笔记

    (feature/xxx)$:?git?add?xxx

    2021-10-31

  • 使用 Gerrit + Zadig 实现主干开发主干发布(含字节跳动飞书实践)

    一个完整的产品交付过程涉及到分支策略、团队的协作流程、基础设施建设等方方面面,高效的协作需要结合项目所处的阶段、产品交付的频率、团队成员的习惯和素养等来制定适合自己团队的方案。详解基于开源 Zadig 团队协作流程及实践细节,工程师如何配置和使用

    2022-06-29

  • 阿里巴巴发布最佳实践 | 阿里巴巴 DevOps 实践指南

    DevOps 追求更短的迭代周期、更高频的发布。但发布的次数越多,引入故障的可能性就越大。更多的故障将会降低服务的可用性,进而影响到客户体验。所以,为了保证服务质量,守好发布这个最后一道关,阿里逐步发展出了适应 DevOps 要求的发布策略。

    2022-03-15

  • SVN 简介

    SVN(Subversion),是一个开放源代码的集中式的版本控制工具,设计目的在于取代CVS,采用了分支管理系统方式,便于多人共同开发同一个项目,使用共同的资源。SVN和CVS有一个共同的特点,那就是采用了C/S模式(客户端/服务器端模式),造成了最大的缺点就是过

    2022-10-28

  • 研发流程设计(下):如何管理应用的生命周期?

    今天,我从技术演进的维度介绍了应用生命周期管理技术,这些技术可以提高应用的研发效率和质量。

    2021-06-12

  • 云效发布策略指南|滚动、分批、灰度怎么选?

    在日常和用户交流过程中,我们也经常会被用户问到关于发布的问题,比如不同职能团队之间应该如何配合、发布的最佳实践应该是什么样子的等等。今天我们就来聊聊常见应用发布方式的选择,以及每种发布模式适合什么样的场景。

    2022-02-28

  • 移除 Staging 环境,加快部署过程

    Squeaky是一家在不侵犯用户隐私的情况下帮助企业了解用户如何访问他们的网站或Web应用程序的公司,它采用了不一样的做法,并解释了为什么他们不使用Staging环境。他们相信这有助于他们更快地发布产品,并减少生产环境中的Bug。

  • 在阿里,我们如何管理代码分支?

    阿里有很多的研发团队,不同事业部使用的发布流程、分支策略并非整齐划一,其中有一种主流的发布模式以及对应的分支使用方式,称为“AoneFlow”。这套工作模式思路独特,在阿里以外的地方并不多见。本文围绕这些实践,聊一聊分支管理的话题。

    2022-02-08

  • 迈向云端:云原生应用时代的平台思考

    在云原生时代,我们需要打造的也应该是一个自动化、服务化、高度扩展的平台。

    2019-12-21

  • git 高效操作之 range revert

    前阵子一个同事因为发现某个分支上的代码好像有缺失导致无法正常运行,然后就对比了下把缺失的代码从另一个分支上拷了过来,可能有所欠考虑,不过主要是说下操作过程和最后的处理方法,这位同学的操作是改一些代码commit 一下

    2022-06-05

  • 直播预告:智能云分支(Cloud Smart Branch)场景和解决方案介绍

    11月24日下午15时,阿里云网络产品解决方案专家 厉羽 将发布“云智能分支(Cloud Smart Branch)场景和解决方案介绍”主题演讲。

    2021-11-18

  • 4 种常见分支模式解析及优劣对比 | 研发效能提升 36 计

    团队研发的本质并不是团队规模越大,研发的效率就越高。我们以为团队规模越大,研发效率就会越高,可以做越多的东西,但是我们发现团队规模大到一定程度,整个研发效率是会下降的,甚至降得非常快。为什么团队的规模越来越大,我们的发布反而越来越慢了?

    2022-03-07

  • 用户故事|只要方向对了,就不怕路远

    通过学习课程,对于遗留系统怎样现代化,我有了更多的思考。

    2022-12-30

  • 平台产品研发:三个月完成千人规模的产品要怎么做?

    关于如何开发产品,在这一讲中,我会把我自己在过去几个项目经历中的经验总结全部分享给你。

    2019-12-17

  • Git-Flow 规范和指令

    在利用Git管理团队代码的时候,都会涉及到如何管理分支,如何发布版本的问题。如果能够制定一套统一的规则,就能够有效的保障团队的开发流程和效率。如下流程主要参考自 A successful Git branching model 进行的一个设计。能够确保各个分支的合理使用,以及

    2021-07-04

  • Java 编程入门经典,linux 使用教程课后答案,mysql 常见笔试题

    分布式系统架构下,服务发布是一件很麻烦的事情,特别是在构建自动发布流程和灰度测试的策略两个核心方面。通常情况下如果不涉及数据层面的灰度流程,服务可以灰度上线,或者滚动上线,这两种方式很常用;如果涉及到数据灰度,则可能需要中间服务做不同版本数

    2021-10-26

  • 什么是分支模式 ? 各 (类) 分支正确的使用方式

    什么是分支模式 ? 本节内容详细介绍分支模式下,各(类)分支的使用方式。在使用分支模式过程中用户可以只需要关心集成和发布哪些 feature 分支,而对 release 分支创建和管理、分支合并等一系列工作,可以托付给云效 Flow来 完成。能够很好的节省我们的时间,

    2022-03-28

  • 期末总结 | 在云时代,如何选择一款合适的流水线工具?

    今天,我来给你梳理一下流行的CI/CD工具,并给你提供一些选择建议。

    2019-12-31

  • 工作流设计:如何设计合理的多人开发模式?

    今天我们来聊聊如何设计合理的开发模式,我会为你介绍4种受欢迎的工作流,你可以选择其中一种作为你的工作流设计。

    2021-06-08

  • 如何通过云效 Codeup 高效落地分支模式,提升开发协作率

    分支模式是我们在进行代码变更时的一种约定,它在版本管理工具(如Git)之上,约定我们在不同分支上的行为,达到提升开发协作效率的目的。云效Codeup 是一款企业级代码管理平台,提供代码托管、代码评审、代码扫描、质量检测等功能,全方位保护企业代码资产,

    2022-04-14

发现更多内容

架构实战营 微信朋友圈高性能复杂度分析

💤 ZZzz💤

架构实战营

Go- 反射

HelloBug

reflect Go 语言

Neon 支持

Changing Lin

9月日更

【8月书单】

姬翔

9月日更

万字长文说透分布式锁

多颗糖

redis zookeeper 分布式 分布式锁 etcd

模块2-作业

笑看风雨情

设计微博系统中”微博评论“的高性能高可用计算架构

架构0期-Bingo

架构师实战营 附一作业(按接口隔离原则优化设计无人机引导直升机攻击的类图)

代廉洁

架构实战营

双非本科跨专业5面京东,8600小时后收到通知,流下喜悦泪水

Java~~~

Java 架构 面试 微服务 JVM

10. 大数据--人工智能的基石

Databri_AI

人工智能

架构实战营 - 模块二作业

en

「架构实战营」

微信朋友圈高性能架构分析-模块二作业

娜酱

#架构实战营

面试题 -- 如何设计一个线程池

秦怀杂货店

线程 线程池 并发

Java + opencv 实现老照片特效滤镜

张音乐

OpenCV 图像处理 9月日更 特效 老照片

微信朋友圈高性能架构

Geek_db27b5

奉若神明!阿里技术专家开源ApacheDubbo核心源码笔记

Java~~~

Java spring 架构 面试 dubbo

阿里技术专家亲码:满干货“Redis核心笔记”,全篇无尿点

Java~~~

Java redis 架构 面试 中间件

技术债的前世今生

码猿外

架构设计 技术债 敏捷精益 软件架构治理

Go- 接口-1

HelloBug

interface Go 语言

Go- 接口-2

HelloBug

interface Go 语言

k8s garbage collector源码分析(2)-处理逻辑分析

良凯尔

Kubernetes 源码分析 Kubernetes源码 #Kubernetes#

Go- 接口-3

HelloBug

interface Go 语言

Django 配置夯实,再补充几个配置项,够够的了

梦想橡皮擦

9月日更

惊讶!阿里大佬总结的图解Java小册火了,完整版笔记开放下载

Java~~~

Java 架构 面试 微服务 JVM

Linux之ssh-agent命令

入门小站

Linux

在线JSON转Csharp工具

入门小站

工具

学生管理系统 - 毕设架构设计

黑鹰

Redis核心原理与实践--字符串实现原理

binecy

redis 书籍推荐 源码学习

ShardingSphere LogicSQL 的生成探索

源码 ShardingSphere

Python开发篇——添加mysqlclient

吴脑的键客

Python MySQL

k8s garbage collector源码分析(1)-启动分析

良凯尔

Kubernetes 源码分析 Kubernetes源码 #Kubernetes#

阿里巴巴如何管理代码分支?_技术管理_林帆_InfoQ精选文章