三类代码协同模式,你要如何选?

三类代码协同模式,Git大神告诉你到底如何选。

Git代码协同模式基础

为团队规划研发协同模式之前,有必要了解Git的几种协同模型。
其中多种协同模型中使用了代码评审。代码评审在不同的代码平台有不同的称谓。
  • GitHub 应该是受到了 git 命令 git request-pull的启发,将代码评审称为拉取请求(pull request, PR)。

  • GitLab 因为代码评审最终被合并(也支持变基 rebase)到目的分支,因而称其为合并请求(merge request, MR)。

  • 阿里云·云效的代码平台,代码评审不但用于分支提交变更的评审,也将支持分支创建、分支删除、强制推送行为的评审,因此云效代码平台将代码评审称为变更请求(change request),简记为 CR。

 

GitHub-Flow:开源社区标配的协同模型

GitHub 在2008年一经推出,就凭借其创造性的“仓库派生 + pull request”的工作流征服了开源社区。这是因为这一协同模式解决了开源社区最大的痛点:仅对少数人开放代码仓库写权限和人人皆可贡献开源的矛盾。

GitHub 工作流的使用

对于开源项目的参与者,可以划分为两类角色:维护者和贡献者。
  • 维护者:具有代码仓库最高权限,可以创建分支、删除分支、更新分支,以及向分支强制推送。

  • 贡献者:没有仓库的写权限,只拥有读权限,不能向代码仓库直接推送。

GitHub 创造了“仓库派生”这一机制,解决了代码仓库的只读用户向代码仓库贡献的途径。我们以 k8s 社区为例,介绍 GitHub 工作流。(图示摘自[1])
GitHub 工作流说明:
  1. 创建派生仓库。说明:作为 k8s 项目的贡献者,没有 k8s 仓库的写权限,但可以通过 GitHub 的 fork 功能将 k8s 项目(kubernetes/kubernetes)派生到自己名下,如仓库 $user/kubernetes。用户对于自己的派生仓库拥有写权限。

  2. 将自己的派生仓库克隆到本地。执行命令:

    • git clone https://github.com/$user/kubernetes.git

  1. 本地仓库和上游仓库分支(如master分支)同步。说明:派生仓库并不能和上游仓库自动同步,为避免本地提交和上游仓库出现过大的偏离导致合并冲突,在每一个功能开发前,以本地仓库为中介,将远程上游仓库的新提交同步到远程的派生仓库中。

    • git remote add upstream https://github.com/kubernetes/kubernetes.git

    • git fetch upstream

    • git switch master

    • git rebase upstream/master

    • git push origin master

  1. 创建一个本地分支(如 mybranch分支)。说明:为每一个开发任务创建一个单独的本地分支是一个好习惯,这样可以在一个本地仓库中,用不同的本地分支关联不同的 pull request。

    • git switch -c mybranch master

  1. 在本地分支中开发。

    • git add <file>

    • git commit -s

  1. 将本地分支推送到远程派生仓库。

    • git push -u -f upstream HEAD

  1. 创建代码评审(pull request)。即:通过 GitHub 的 Web 界面,从远程派生仓库向远程上游仓库创建 pull request。

  2. 本地仓库中新的改动(提交)再次推送到远程的派生仓库,会自动刷新代码评审中的提交。

优势和缺点

GitHub-Flow 的优势:
  1. 满足了开源项目人人皆可贡献的目标。在2008年,仓库派生是基于原生 Git 实现开源协同的最易用的方案。

  2. 易于管理。将代码管理工作化整为零,每个派生仓库由派生者自行管理,开源项目的负责人无需进行复杂的授权管理和分支管理。

  3. 派生仓库是一个独立的拷贝,不会受到上游变更(许可证变更、开放性变更、授权变更等)的影响。
GitHub-Flow 的缺点:
  1. 仓库同步操作复杂。同步操作涉及到远程上游仓库、远程派生仓库、本地克隆仓库的三方数据同步,开发者要熟悉 git remote、git rebase等命令。

  2. 派生熔断导致仓库授权失去管控。在仓库的开放性发生变更(例如从公开项目转换为私有项目),主项目和派生项目之间的派生关系被切断,成为没有派生关系的不同的项目,派生项目的管理权也从主项目自动交接给派生项目的用户。

  3. 不适合于多仓库类型的项目(如 Android 项目)。由于多仓库的存在,放大了派生仓库和上游仓库同步的复杂度。

  4. 派生仓库导致服务端存储出现冗余。

上述缺点,尤其是派生熔断导致仓库授权失去管控,无法被企业管理者所接受。因此,GitHub 工作流只适合于外部开源或者企业内部开源项目,而不适合企业私有项目。

 

分支评审:仅适用于私有仓库的协同模型

GitHub 的派生工作流会因为仓库可见性从公开变为私有导致派生熔断,造成仓库授权失去管控,因此派生仓库协同模式通常不被企业所接受。进而,被所有代码平台所支持的分支评审模式自然成为企业私有仓库协同的最直观的选择。

分支评审模式的使用

企业私有代码仓库的协同者通常包含三类角色:管理员、开发者、贡献者。
  • 管理员:即仓库的维护者,具有代码仓库最高权限,可以创建分支、删除分支、更新分支,以及向分支强制推送。

  • 开发者:具有仓库的读写权限,除了不具备删除仓库等危险操作的权限之外,和管理员一样,具有创建分支、删除分支、更新分支,以及向分支强制推送的权限。

  • 贡献者:没有仓库的写权限,只拥有读权限。

上述三个角色中,只有开发者和管理者拥有写权限,因此只有这两种角色才能够使用分支评审模式参与代码仓库的协同。
采用分支评审模式协同,开发者在服务端仓库中创建临时分支,将本地提交推送到相应的临时分支上,再从该临时分支创建到目标分支的代码评审。临时分支通常在代码合入后清除。用户在服务端创建的临时分支,根据目标分支的不同,有着不同的名称。如:
  • 特性分支(topic branch):为完成某一功能开发而创建的临时分支,通常基于主干分支创建。不同的项目对于特性分支可能有不同的命名规范,例如:topic/<name>、feature/<name>。
  • 热修复分支(hotfix branch):为修复已发布的历史版本的缺陷,基于历史发布版本(如 v1.0 版本)创建的分支。不同的项目对于热修复分支可能有不同的命名规范,例如:hotfix/<name>。

下面的示意图演示了一个开发者如何通过分支模式将特性分支(如 topic/1)合入到主干分支(如 master)。
说明如下:
  1. 开发者将远程仓库克隆到本地:

    • git clone https://example.com/group/repo.git

  1. 本地创建分支,如 topic/1分支:

    • git switch -c topic/1

  1. 在本地分支中开发。

    • git add <file>

    • git commit -s

  1. 将本地 topic/1分支推送到远程服务器上。

    • git push -u origin HEAD

  1. 开发者访问 Web 界面,选择从 topic/1分支向 master分支创建代码评审(如编号 123 的代码评审CR #123)。

  2. 本地仓库继续修改,创建或更新提交。

    • git add <file>

    • git commit -s

  1. 执行推送命令,自动刷新远程仓库中的代码评审(CR #123)。

    • git push

  1. 代码评审通过,从 Web 界面访问 CR#123,点击合入完成分支 topic/1到分支 master的合入。

  2. 分支 topic/1合入后,可以手工删除该分支。

GitLab 的保护分支功能

保护分支功能最早由 GitLab 实现,目的是确保分支能够严格采用分支评审模式进行协同。
  • 通过输入名称通配符,确保与之匹配的分支被加以保护。

  • 可以设置被保护的分支必须使用代码评审才能够合入,不能直接推送。

  • 可以设置被保护的分支不能够被强制推送,管理员也不例外。

保护分支由管理员进行设置,通常仅对代码仓库的主干分支、维护分支进行保护,而不对特性分支进行保护。

优势和缺点

分支评审模式的优点:
  1. 如果某个特性的开发周期比较长,创建一个长期存在的特性分支,便于开发者能够随时执行推送命令将本地提交推送到服务端,避免本地误操作而丢失数据。

  2. 如果某个特性由多人协同开发,设置一个特性分支,便于多个用户进行工作协同。

分支评审模式的缺点:
  1. 如果开发者无论是否必须、无论特性的大小,都采用分支评审模式,且不能及时删除过时的特性分支,就会在服务端遗留大量过时的分支。仓库中过多的特性分支和仓库的核心分支(主干、维护分支)混杂,会给开发者带来困惑,也会导致用户操作过程的性能下降。

  2. 缺乏有效的分支授权管控,无法限制对于非保护分支的推送、创建、删除权限的管控,可能导致特性分支被误删,或者特性分支因多人协同时强制推送被覆盖,造成代码丢失、协同效率的下降。

分支评审模式的改进

采用 AGit-Flow 协同模式,直接通过命令行创建代码评审,而不在仓库中创建临时分支,可以解决了分支评审模式中特性分支过多、混乱的问题。
至于分支评审模式缺乏对特性分支创建、删除、强制更新的授权,阿里云·云效代码平台提供推送评审模式,实现自助式分支管理,以解决代码仓库中分支管理无序的难题。

 

AGit-Flow:兼顾开源和私有项目的集中式协同模型

阿里巴巴内部的代码平台在2019年实现了一种集中式工作流——不需要仓库派生,就可以让只读用户贡献代码。这种集中式工作流既适合于开源项目,又适合于私有项目。因其核心实现基于阿里云代码团队定制版的Git(AGit),因此将此工作流命名为 AGit Flow。
AGit Flow在设计上参考了 Gerrit,使用体验和 Gerrit 类似。在2020年,阿里巴巴将这一成果核心代码贡献到Git社区,对Git服务端和Git客户端能力进行了扩展。参见:《Git2.29让Git成功“牵手”Gerrit》[2]。
在2023年6月,由阿里云代码团队参与建设的AtomGit开源平台上线,标志着首次将 AGit 工作流带入到了开源社区(atomgit.com)[3]。

AGit 工作流的使用

AGit 工作流在设计上参考了 Gerrit。
Gerrit 是谷歌开发的代码平台,被Android、OpenStack 等项目拿来管理各自的研发协同。Gerrit 的仓库格式也是 Git,但是服务端实现采用了 Java 开发的Git兼容工具 jGit 而非原生 Git,除了带有谷歌风格的逐提交代码评审之外,还实现了无需派生仓库、所有贡献者基于同一个上游仓库进行协同的集中式工作流。Gerrit 这一集中式工作流既适合开源项目,也适合私有项目。但是因为 jGit 在性能和功能上落后于原生 Git,且 Gerrit 的使用体验、可扩展性存在的问题,导致 Gerrit 协同模式没有 GitHub 工作流那样的被人熟知和使用广泛。
在2020年,阿里巴巴向 Git 社区贡献两个功能扩展[4],一个成为Git服务端的功能扩展(proc-receive 挂钩),一个成为Git客户端功能扩展(report-status-v2 能力)。这样代码平台的设计者可以在服务端针对用户的 git 推送行为进行相应的扩展,体验上类似Gerrit,但是能力更加强大。即:
  • 用户向仓库的特殊引用(如refs/for/master)推送,生成代码评审。其中特殊引用 refs/for/master在服务端并不存在,也不会因为用户的推送操作而被创建,用户的推送操作被服务端扩展程序接管,创建代码评审。

  • 客户端收到服务端操作的真实结果,并向用户报告。例如:Git客户端通过 report-status-v2协议接收到服务端真实的操作行为,在服务端创建了代码评审(如:refs/changes/123/head)。
在如下的示例中,有两个角色参与到协同中。开发者向服务端仓库推送,创建了编号为123的代码评审(CR#123),评审者亦能下载、修改和上传代码评审中的提交。
上图中的开发者,执行如下操作:
  1. 开发者将远程上游仓库克隆到本地,并在本地创建开发分支。

    • git clone https://codeup.aliyun.com/$group/$repo.git

  1. 开发者创建本地分支(topic)。

    • git switch -c topic master

  1. 在本地分支中开发。

    • git add <file>

    • git commit -s

  1. 执行特别的推送命令。如下所示,将本地提交推送到远端不存在也不会被创建的一个虚拟分支(引用)中,该虚拟分支的格式为 refs/for/<目标分支>/<本地分支>。服务端识别这个特殊的推送操作,在服务端创建代码评审。

    • git push origin HEAD:refs/for/master/topic

  1. 上述推送命令的特殊目标分支被服务端识别,自动创建代码评审(如编号 123 的代码评审:CR #123)。

  2. 本地仓库继续修改,创建或更新提交。

    • git add <file>

    • git commit -s

  1. 执行同样的推送命令,刷新远程仓库中的代码评审(CR #123)。
上图中的代码评审者参与代码评审过程中,可以下载代码评审(CR #123)到本地进行线下评审,亦可参与代码协同,更新 CR #123 上的提交。说明如下:
  1. 评审者可以下载编号 123 的代码评审相关提交到本地,进行线下评审。

    • git fetch origin refs/changes/123/head

  1. 评审者创建本地分支(如 rev-branch)。

    • git switch -c rev-branch FETCH_HEAD

  1. 评审者在本地分支创建新提交。

    • git add <file>

    • git commit -s --fixup HEAD

  1. 评审者执行特殊推送命令,更新代码评审中的提交,供原作者参考。该命令中使用了特别的推送参数 -o review=123用于更新指定代码评审。示例如下:

    • git push -o review=123 origin HEAD:refs/for/master

优势和缺点

AGit-Flow 的优势:
  1. 人人皆可贡献,只读用户也可以参与代码开发,适合于开源场景。

  2. 同时也适合于企业私有仓库的开发场景。因为不存在仓库派生,不像 GitHub 工作流那样因派生熔断导致仓库授权失去管控,因此既适合于开源代码开发场景,又适合于企业私有项目的开发场景。

  3. 开发者工作在同一个仓库中,服务端仓库无需同步操作。即不需要 GitHub 工作流那样要进行上游仓库、派生仓库、本地仓库的三方同步操作。

  4. 操作步骤简化,命令行推送操作直接创建代码评审,无需通过 web 界面创建代码评审。

  5. 适合于多仓库项目的场景。可以参考 Android 项目管理多仓库的方案。

AGit-Flow 的缺点:Git 推送命令行比较长,使用特殊的目标引用(refs/for/<branch>/<topic>)或特殊的推送参数,需要学习和适应。

 

推送评审模式

基于阿里云贡献给 Git 社区的两大核心功能(服务端 proc-receive 挂钩和客户端 report-status-v2 扩展),阿里云·云效代码平台创造了推送评审模式,实现对仓库分支、标签的全生命周期管理。
推送评审模式内部测试中,将于2023年底正式商用。
推送评审的使用方法:
  • 向已有分支推送:不更新分支,而是创建一个新的代码评审,或更新已有的相关代码评审。

  • 推送操作欲创建分支/标签:不直接创建分支/标签,而是创建一个审核单,审核通过后执行分支/标签的创建操作。

  • 推送操作欲删除分支/标签:不直接删除分支/标签,而是创建一个审核单,审核通过后执行分支/标签的删除操作。

  • 向分支强制推送:不更新分支,而是创建一个审核单,审核通过后执行分支的强制更新操作。

  • 管理员可以在推送命令中加入参数绕过推送评审,使得推送操作直接生效。如:

    • git push -o review=no origin <新分支> :<待删除分支>

    • git push -o review=no --force-with-lease

设计团队的代码协同工作流

基于前面介绍的代码协同模式,企业/团队根据项目的实际情况可以灵活定制自己的代码协同工作流。通过对以下问题的回答,可以找出最适合的代码协同工作流。

 

团队能力和项目类型评估

是否开源?

开源包括针对外部的代码开源,还包括企业内部开源(内源)。
如果代码仓库选择了开源(无论是外部开源,还是内源),为管理方便可以在仓库中仅定义两种用户角色:
  • 维护者。维护者可以是一个人或者一个团队承担项目维护者的职责,维护者具有仓库读写和管理权限。管理权限包括:批准代码评审通过,合并代码评审等。

  • 贡献者。贡献者具有只读权限,需要通过 GitHub-Flow 或者 AGit-Flow 方式向仓库贡献代码。

对于复杂的需要多人协同开发的特性,可以采用 GitHub-Flow 模式。通过创建的派生仓库进行多人协同开发,开发完毕创建向上游仓库的代码评审。代码评审通过,将提交合入到上游代码仓库。
对于简单的特性开发,建议采用 AGit-Flow 模式,用户执行 git 推送命令,直接在服务端创建代码评审。对处于开发中尚不具备合入质量的提交,为了避免本地数据丢失,或者希望在服务端触发持续构建(CI)检查代码质量,可以通过如下推送命令在服务端创建草稿模式的代码评审:
  • git push origin HEAD:refs/drafts/<branch>/<topic>

草稿状态的代码评审不能被合入,但是可以触发CI构建,可以进行代码评审。

是否有旧版本需要维护?

通常互联网线上应用采用持续部署(CD)、主干分支发布。这种类型的项目一旦发现线上缺陷,直接在项目的主干分支上修复缺陷,修复缺陷的提交连同新特性一同发布到线上。这种类型的项目不需要对旧版本进行维护。
有的项目无法采用持续部署、持续发布,新版本有较长的开发周期,就需要对已发布的一个或多个版本进行维护。这样的项目就需要在代码仓库中存在一个或多个维护分支。例如:安卓手机的 Android 系统、苹果手机的 iOS 系统通常在每年发布一个大版本,历史发布版本提供长达几年的维护期,这就需要在产品的代码仓库中创建一个或多个维护分支。
不同的项目对于维护分支可能有不同的命名规范,例如:maint、maint-2.0、maint-3.0。

是否使用CI和代码评审?

使用持续构建(CI)和代码评审,可以确保贡献者提交的正确性和代码质量,是软件项目高质量交付的利器。缺乏CI能力,也可以使用代码评审,不过缺乏CI的代码评审更加消耗评审人的时间,且难以保证代码的正确性。
对于缺乏代码评审文化、缺乏单元测试、不具备CI条件的项目,往往跳过代码评审,这种类型的项目通常采用类似CVS、SVN的共享分支协同模式。
即使采用代码评审的项目,对于多人协同开发的复杂特性通常创建一个长期的特性分支,多人在同一个特性分支进行代码协同时,通常也采用共享分支协同模式。
对于共享分支协同的建议:
  • 多个开发者向服务端仓库的同一个分支推送,先推送者成功,后推送者遇到非快进式推送被拒绝,需要采用正确的行为规范,避免强制推送造成其他人的提交被覆盖、丢失。推荐的操作方式是:

    • 推送之前先执行拉取和变基操作:git pull --rebase。

    • 再执行推送操作:git push。

  • 使用保护分支功能,设置被保护的分支不能强制推送,不能被删除。这样向保护分支推送时需要采用上面的操作建议,先和服务器同步、变基操作,再推送。

  • 当发现推送了错误的提交,希望采用强制推送覆盖服务器上推送的提交时,不要使用 git push --force,而是使用 git push --force-with-lease命令,为强制推送增加一份保险。注意:替换的服务器端提交如果已被他人获取,强制推送可能为他人带来困扰。

根据CI和代码评审的频率来判断项目的规模

当代码仓库的主干分支上有多个待合并的代码评审(CR),合并其中一个CR到主干,主干分支上的代码会发生变化,这会导致其他尚未合并的 CR 的构建状态变得没有意义,需要重新执行构建以确保正确性。总的构建规模和CR数量关系为 O(n2) ,庞大的CI构建规模造成巨大的时间成本、计算成本的浪费,此外CR需以排队构建方式合入主干分支,导致项目协同规模受限。
我们可以采用下面的公式判断项目协同规模,决定是否采用集成分支以并行方式合入代码、降低 CI 构建数量。
项目复杂度 = 每日新建CR数量 / 每日串行CI构建数量
每日串行CI构建数量 = 8小时 / 单次CI构建时间
或简记为:
项目复杂度 = NT / 8
其中:
  • N:每日新建 CR 数量。

  • T:单次CI构建时间(单位:小时)。

当项目复杂度大于等于1,视为中大型项目,需要引入集成分支提升 CI 构建效率,CR先批量合并到集成分支,再合入主干。
当项目复杂度小于1,视为小型项目,仅使用主干分支即可,CR直接合入主干分支。

 

示例:小型项目(无维护分支)协同规范

对于小型项目(无维护分支),采用主干开发模式。存在一条主干(如 master分支),功能开发通过特性分支模式或者 AGit-Flow 模式创建评审,代码评审触发持续集成(CI),评审通过之后,代码直接合并到主干分支。
协同示意图如下所示,其中提交之间的箭头方向表示的是时间从老到新的方向。

项目成员管理

项目成员分属三个角色:管理员、开发者和贡献者。
  • 管理员:由一位或几位核心成员担任,具有对仓库完全的读写权限。

  • 开发者:固定的项目成员,对于仓库中非保护分支具有完全的读写权限。

  • 贡献者:团队之外的成员属于贡献者,仅有仓库的只读权限。

分支的命名和管理

设置一条主干分支作为仓库的默认分支。主干分支通常命名为 master或 main,由仓库管理员在仓库初始化时创建。
分支管理规范:
  • 可以使用通配符“*”设置保护分支,即所有分支均被保护。

  • 管理员和开发者能够在仓库中创建新分支,或者在推送评审模式启用下,任何人均可通过创建评审单的方式创建新分支。

  • 如果所有分支均被保护,则开发者创建的特性分支也需要使用 AGit-Flow 工作流创建代码评审,将提交合并到特性分支中。

  • 向特性分支发起的代码评审,默认采用变基(rebase)方式合并,以避免在特性分支产生合并提交。

  • 向主干分支发起的代码评审,默认采用非快进合并(no-ff merge)方式合并。这种方式一定会产生一个合并提交,在合并提交中记录代码评审 CR 的编号和 CR 的描述信息。

  • 特性分支合入到主干分支时,默认选择合并后删除分支,避免过时的特性分支在仓库中堆积。

创建代码评审

可以采用三种方式创建代码评审:GitHub Flow、AGit Flow、分支评审模式。代码评审创建、更新会触发持续集成。
操作略。

持续集成(CI)

针对如下场景触发持续集成:

  • 向主干分支、特性分支的代码推送,触发持续集成。

  • 创建和更新 CR,触发持续集成。

  • CR 的目标分支被更新,触发持续集成。为避免 CR 构建规模造成的资源浪费,会检查开启的 CR 数量,当仓库复杂度超过阈值(NT/8 >= 1)则应关闭 CR 随目标分支变更而自动构建的设置。

 

示例:大型私有项目(含维护分支)协同规范

对于大型项目(含维护分支),存在一条主干(如 master分支)、一条或多条维护分支(如 maint分支)。功能开发通过特性分支模式或者 AGit-Flow 模式创建评审。创建或更新代码评审会触发持续集成,持续集成验证通过以及代码评审通过之后,首先将代码合入到集成分支(如 next分支),触发集成分支的持续集成,验证通过后再整合入主干分支。发行版本(如 v1.0.0)的缺陷修复,需要创建一条维护分支(如maint分支),基于该维护分支创建热修复分支或者使用 AGit-Flow 模式创建针对维护分支的代码评审。针对维护分支的代码评审验证通过后,先合入到维护分支,然后将维护分支回合到主干分支,以确保在历史版本中出现的问题在主干代码中亦得到修复,相同问题不再重现。
协同示意图如下所示,其中提交之间的箭头方向表示的是时间从老到新的方向。

项目成员管理

项目成员分属三个角色:管理员、开发者和贡献者。
  • 管理员:由一位或几位核心成员担任,具有对仓库完全的读写权限。

  • 开发者:固定的项目成员,对于仓库中非保护分支具有完全的读写权限。

  • 贡献者:团队之外的成员属于贡献者,仅有仓库的只读权限。

分支的命名

在仓库中设置如下常设分支:
  • 一条主干分支:master(或 main),同时作为仓库的默认分支,由仓库管理员在仓库初始化时创建。

  • 一条或多条维护分支:作为对一个或多个已发布版本的缺陷修复,仅合入缺陷修复提交,不合入新功能。可选的名称有:maint、maint-1.0、release/1.0、release/2.0等。Git项目使用 maint作为维护分支名,因为按照字母序,维护分支maint排在主干分支 master之前,意味着更稳定。

  • 一条集成分支:该分支作为主干分支的集成分支,每一次集成的时候自主干分支重置,批量合入已经通过评审的 CR。批量合入后触发CI构建。Git项目中集成分支命名为 next,字母序排在 master之后,视为不稳定的分支。

分支管理规范

保护分支的设置:
  • 可以使用通配符“*”设置保护分支,即所有分支均被保护。

  • 管理员和开发者能够在仓库中创建新分支,或者在推送评审模式启用下,任何人均可通过创建评审单的方式创建新分支。

  • 因为所有分支被保护,开发者创建的特性分支、hotfix分支等也需要使用 AGit-Flow 工作流创建代码评审,将提交合并到相关分支中。

维护分支的管理规范:
  • 发现历史版本的缺陷后,基于存在缺陷最老的维护分支进行缺陷修复。

  • 可以采用创建 hotfix 分支的分支评审模式,或者采用 GitHub Flow 或者 AGit Flow 模式发起针对维护分支的代码评审。hotfix 分支的命名示例:hotfix/<name>。

  • 向维护分支发起的代码评审通过之后,合入相应的维护分支。之后将修复的维护分支逐级合并到更高版本的维护分支,将缺陷修复“扩散”到所有版本中,即 “merging upwards”。

  • 将修复后的最新维护分支合并到主干分支。

集成分支管理规范:
  • 将通过评审的多个 CR 自动或手工合入集成分支(如 next分支)。

  • 更新后的集成分支触发构建。

  • 集成分支构建成功后,通过界面发起集成分支到主干分支的合并请求。

主干分支管理规范:
  • 中大型项目设置了集成分支,因此针对主干分支的代码评审不直接合入主干分支。
  • 在集成分支(如 next分支)CI构建通过之后,重新合并到主干分支(以确保合并提交的提交说明的目标分支从 next调整为 master),更新主干分支提交,并触发构建。

特性分支规范:
  • 向特性分支发起的代码评审,采用变基(rebase)方式合并,避免在特性分支产生合并提交。

  • 向主干分支发起的代码评审,采用非快进合并(no-ff merge)方式合并。这种方式一定会产生一个合并提交,在合并提交中记录代码评审 CR 的编号和 CR 的描述信息。

  • 特性分支合入到主干分支时,选择合并后删除(可以设置为默认开启),避免过时的特性分支在仓库中堆积。

创建代码评审

可以采用三种方式创建代码评审:GitHub Flow、AGit Flow、分支评审模式。代码评审创建或更新会触发持续集成。
操作略。

持续集成(CI)

针对如下场景触发持续集成:
  • 向主干分支、集成分支、特性分支、维护分支的代码推送,触发持续集成。

  • 创建和更新 CR,触发持续集成。

  • CR 的目标分支被更新,不触发 CR 的持续集成,以降低 CR 构建的复杂度。

参考链接:

[1]https://www.kubernetes.dev/docs/guide/github-workflow/

[2]https://developer.aliyun.com/article/776452
[3]https://atomgit.com/
[4]https://developer.aliyun.com/article/776452
作者|知忧

热门相关:有个人爱你很久   今天也没变成玩偶呢   拒嫁豪门,前妻太抢手   大妆   大妆