目录:
本文解决什么问题?
你是否有过这样的经历:当思考如何使用 Git 对多人协作开发进行管理时,总感觉有些思路,但不够清晰,甚至实施起来不尽如意,尤其是当协作复杂度升高时,又需要绞尽脑汁地重新设计。
造成这种现象有以下几个原因:
- Git 的分支机制是为版本管理而设计的,并不是为权限、协作管理而设计的,所以,当用于权限、协作管理时,显得不够直观。
- 对协作管理没有清晰的认知,总是将协作管理 和 分支流转管理混为一谈,导致经常参合在分支流转规范(如:
GitFlow
)中一块思考协作管理的问题,大大增加了复杂度。 - 没有系统、深入地总结、理解过各种协作管理方案。
- 对 Git 的分布式、仓库、分支没有深入的理解和认识。
本文就系统地总结、抽象了各种协作管理方案而且还可灵活组合,并总结了各个方案的特性。对任意复杂度的协作项目,你都可以根据需要来快速地选择或组合出协作管理方案。
说明
仓库级管理和分支级管理
以下这些协作管理方案不但可以用于仓库级(多个仓库)的管理,也可用于分支级(同一仓库中的多个分支)的管理,所以,为了更加通用,下面的方案并没有具体表明是仓库 还是 分支:
- 当将方案应用于仓库时:
- 方案中的每个远程表示就是其对应的远程仓库;
- 每个人员是在自己的本地仓库上进行操作;
- 从其他人员的远程上拉取的操作便提
fork
操作。
- 当将方案应用于分支时:
- 方案中的每个远程表示就是其对应的远程分支;
- 每个人员是在自己的本地分支上进行操作;
- 从其他人员的远程上拉取的操作便提 合并 操作。
合并请求
- 申请合并的请求,称为
合并请求
;在有些环境(如:GitHub)也称为拉取请求
,但称为合并请求
更为直观,所以下文统称为合并请求
; - 如果处理 合并请求 是在云端(如:GitHub、GitLab、Gitee)操作的,那么对操作者来说从主观的感知上,以下操作就被隐式地合并成了一个操作:
- 拉取被请求合并的变更;
- 合并变更;
- 将合并后的变更推送到远程;
这样的话,以下各个协作管理方案图中的那些角色和其对应的远程可以当作一个整体来对待,这样可以使图更易理解。
基础协作管理方案
我称下面这些协作管理方案为基础协作管理方案,之所以称为基础,并不是因为它们简单,相反它们并不简单,而是因为这些方案可以相互组合,形成更复杂的混合方案。
总线式协作管理
这种协作管理方式中,只有开发者一个角色,没有明确的管理员,大家共享同一个远程。
协作流程:
- 开发者都从同一个远程上拉取代码;
- 开发者各自进行开发;
- 在需要推送到远程前,合并远程上的最新变更;
- 推送到远程;
特点:
- 没有管理角色,只有开发角色。
- 协作方式简单,适合较简单的小项目。
流水线式协作管理
这种协作管理方式中,有以下角色:
- 开发者:可以有一个或多个,负责项目的具体开发。开发完成后,将项目交付给测试者进行检测。
- 测试者:负责检测项目是否有问题。检测完成后,将项目交付给下一个测试者 或 发布者。
- 发布者:负责项目最终的交付,比如:将项目发布上线等。
其中:
- 项目的标准位置是在开发者的远程中。开发者拥有完整的项目代码。
- 项目的交付顺序是流水线式的:
开发者 -> 测试者 -> 测试者 -> 发布者
。 - 每个人员都有自己的远程。
- 每个人员的上游都是上一个交付者的远程,即:每个人员都管控着上一个交付者的下游(出口)。
协作流程:
- 开发者进行开发,并将产生的变更推送到自己的远程上;
- 当开发完毕后,从开发者的远程上向测试者发起 合并请求;
- 测试者接受请求并合并开发者的变更,并进行检测;
- 测试者测试完成后,将合并后的变更推送到测试者的远程;
- 从测试者的远程上向下一个交付者发起 合并请求;
- 如果下一个交付者仍是测试者,则跳到 步骤 3;否者继续;
- 发布者接受请求并合并测试者的变更;
-
发布者将合并后的变更推送到发布者的远程;
特点:
- 流水式的交付流:适合那种具有流水作业的协作管理机制,比如:
开发->测试->发布
;
扁平式协作管理
这种协作管理方式中,有以下角色:
- 管理员:只有一个管理员,管理员有权决定是否采用开发者的变更。
- 开发者:可以有一个或多个,负责项目的具体开发。
其中:
- 项目的标准位置是在管理员的远程中。
- 每个人员都有自己的远程。
- 每个人员的上游都是管理员的远程,即:管理员管控着每个人员的上游(入口)。
- 每个人员的下流都是管理员,即:管理员管控着每个人员的下游(出口)。
协作流程:
- 开发者从管理员的远程上拉取代码;
- 各个开发者各自开发,并将产生的变更推送到自己的远程上;
- 当开发完毕后,把管理员的远程上最新的变更合并进来,并推送到自己的远程上。
- 从开发者的远程上向管理员发起 合并请求。
- 管理员决定是否接受请求,如果拒绝,则终止流程。
- 如果管理员接受请求,则合并开发者请求的变更。
-
管理员将合并后的变更推送到管理员的远程。
特点:
- 有一个管理员,可实现项目管控;
- 管理员管控着所有开发人员的上下游(入口和出口);
- 适合一般的项目开发;
层级式协作管理
这种协作管理方式中,有以下角色:
- 管理员:只有一个管理员,负责管理组长,管理员有权决定是否采用组长的变更。
- 组长:根据需要可以有任意多个,负责管理开发者 或 组长(子级组长)。
- 开发者:可以有一个或多个,负责项目的具体开发。
其中:
- 项目的标准位置是在管理员的远程中。
- 每个人员都有自己的远程。
- 每个人员的上游都是管理员的远程,即:管理员管控着每个人员的上游(入口)。
- 管理员管控着直接组长的下游(出口)。
- 组长管控着开发者或子级组长的下游(出口)。
协作流程:
- 开发者和组长从管理员的远程上拉取代码;
- 各个开发者各自开发,并将产生的变更推送到自己的远程上;
- 当开发完毕后,把管理员的远程上最新的变更合并进来,并推送到自己的远程上。
- 从开发者的远程上向组长发起 合并请求。
- 组长决定是否接受请求,如果拒绝,则终止流程。
- 如果组长接受请求,从管理员的远程上拉取最新的变更,并合并开发者请求的变更。
- 组长将合并后的变更推送到组长的远程。
- 从组长的远程上向管理员发起 合并请求。
- 管理员决定是否接受请求,如果拒绝,则终止流程。
- 如果管理员接受请求,则合并组长请求的变更。
-
管理员将合并后的变更推送到管理员的远程。
特点:
- 有一个管理员,可实现项目的最高级别的管控;
- 管理员管控着组长的上下游(入口和出口);
- 管理员管控着所有开发者的上游(入口);
- 有多个组长,组长还可管理子级组长,可实现分而治之,比如:
- 分担管理员的管理工作;
- 将项目分成多个模块,每个组长负责一个模块;
- 组长管理着其成员的下游(出口);
- 适合大型的项目开发;
混合式协作管理方案
在一个协作管理方案中,可以组合使用以上基础协作管理方案,从而形成一个混合的协作管理方案。
特点:
- 根据业务需要,随意组合。
混合方式介绍
因为可组合的情况较多,这里就以 组合 层级式协作管理方案 和 扁平式协作管理方案 为例,来展示下如下组合:
它与 层级式协作管理方案 很像,唯一的变化就是:开发者1
和 开发者2
原来是从 管理员的远程中拉取(或fork)变更,而现在是从 组长1
的远程中拉取(或fork)变更。
它是在 层级式协作管理方案 基础上,将 组长1
及以下所管理的成员使用 扁平式协作管理方案 进行管理。其中:
-
组长1
是开发者1
和开发者2
的管理员;它管控着开发者1
和开发者2
的上下游(入口和出口):-
开发者1
和开发者2
都从组长1
(也就是 扁平式协作管理方案 中的管理员) 的远程上拉取(或fork)变更,即:组长1
管控着下面成员的上游(入口)。 -
开发者1
和开发者2
都会将合并请求发送给组长1
,即:组长1
管控着下面成员的下游(出口)。
-
开测预发协作管理方案
开测预发协作管理方案 就是应用于 开发+测试+预发布+发布 场景下的协作管理方案。
这个场景下有以下几个角色:
- 开发人员:普通开发人员,往往会有多个;开发完毕后交给 开发组长 审查。
- 开发组长:项目开发的负责人;审查完毕后交给 测试人员 测试。
- 测试人员:测试人员;测试完毕后;发布到预发布环境;如果没有预发布环境,直接发到发布环境。
- 预发布人员:预发布环境的负责人;预发布环境运行测试没问题后,转到发布环境;如果没有预发布环境,也可省略此角色。
- 发布人员:发布(正式)环境的负责人。
这几个角色的交接顺序是:所有开发人员 -> 开发组长 -> 测试人员 -> 预发布人员 -> 发布人员
。
根据这些角色关系,它们的协作管理方案可以如下设计:
-
开发组长 -> 测试人员 -> 预发布人员 -> 发布人员
使用 流水线式协作管理方案; - 开发组长采用 扁平式协作管理方案 来管理 开发人员。
协作流程:
- 开发者从开发组长的远程上拉取代码;
- 各个开发者各自开发,并将产生的变更推送到自己的远程上;
- 当开发完毕后,把开发组长的远程上最新的变更合并进来,并推送到自己的远程上。
- 从开发者的远程上向开发组长发起 合并请求。
- 开发组长决定是否接受请求,如果拒绝,则终止流程。
- 如果组长接受请求,则合并开发者请求的变更。
- 组长将合并后的变更推送到组长的远程。
- 从组长的远程上向测试者发起 合并请求。
- 测试者接受请求并合并开发者的变更,并进行检测;
- 测试者测试完成后,将合并后的变更推送到测试者的远程;
- 从测试者的远程上向 预发布者 发起 合并请求;
- 预发布者接受请求并合并测试者的变更,然后在预发布环境下试运行;
- 预发布者将合并后的变更推送到发布者的远程;
- 发布者接受请求并合并预发布者的变更;
-
发布者将合并后的变更推送到发布者的远程;
特点:
- 有 开发者、开发组长、测试者、预发布者、发布者,符合大多数项目的角色安排。
稳妥型开测预发协作管理方案
在 开测预发协作管理方案 中,开发组长管理着完全的项目代码,所以它没有上游。但在一些使用 GitFlow规范 的项目中,修复分支需要分支合并到母分支 和 开发分支 中,在实际操作中可能会常常忘记合并到开发分支 或者 有些变体规范中 不要求合并到 开发分支,这就会导致 发布分支 上存在一些没包含在 开发分支 中的代码。
所以,为了保证开发分支中包含 发布分支 上所有的代码,可以在 开测预发协作管理方案 的基础上,让开发组长每次推送到远程前,先合并一下发布者远程上的代码,即:把发布者的远程作为开发组长的上游。如下图:
这个场景下的角色和 开测预发协作管理方案 的完全一样,如下:
- 开发人员:普通开发人员,往往会有多个;开发完毕后交给 开发组长 审查。
- 开发组长:项目开发的负责人;审查完毕后交给 测试人员 测试。
- 测试人员:测试人员;测试完毕后;发布到预发布环境;如果没有预发布环境,直接发到发布环境。
- 预发布人员:预发布环境的负责人;预发布环境运行测试没问题后,转到发布环境;如果没有预发布环境,也可省略此角色。
- 发布人员:发布(正式)环境的负责人。
这几个角色的交接顺序是:所有开发人员 -> 开发组长 -> 测试人员 -> 预发布人员 -> 发布人员
。
根据这些角色关系,它们的协作管理方案可以如下设计:
-
开发组长 -> 测试人员 -> 预发布人员 -> 发布人员
使用 流水线式协作管理方案; - 开发组长采用 扁平式协作管理方案 来管理 开发人员。
协作流程: 只是在 开测预发协作管理方案 的协作流程 上平加了 第5、第6 这两条
- 开发者从开发组长的远程上拉取代码;
- 各个开发者各自开发,并将产生的变更推送到自己的远程上;
- 当开发完毕后,把开发组长的远程上最新的变更合并进来,并推送到自己的远程上。
- 从开发者的远程上向开发组长发起 合并请求。
- 👉开发组长合并发布者的远程的新变更。
- 👉开发组长将合并后的变更推送到开发组长的远程。
- 开发组长决定是否接受请求,如果拒绝,则终止流程。
- 如果组长接受请求,则合并开发者请求的变更。
- 组长将合并后的变更推送到组长的远程。
- 从组长的远程上向测试者发起 合并请求。
- 测试者接受请求并合并开发者的变更,并进行检测;
- 测试者测试完成后,将合并后的变更推送到测试者的远程;
- 从测试者的远程上向 预发布者 发起 合并请求;
- 预发布者接受请求并合并测试者的变更,然后在预发布环境下试运行;
- 预发布者将合并后的变更推送到发布者的远程;
- 发布者接受请求并合并预发布者的变更;
-
发布者将合并后的变更推送到发布者的远程;
特点:
- 有 开发者、开发组长、测试者、预发布者、发布者,符合大多数项目的角色安排。
- 相比 开测预发协作管理方案 更具稳妥性。