再论分支管理问题。

单模块的分支管理

git解决了单项目的分支管理问题。但是这只是一个模块的分支管理。

一个模块内的版本可以是:

  • main
  • dev
  • somebody/dev
  • somebody/feature/xxx

多模块的分支管理

当出现 N 个模块组成的系统的时候,版本管理开始“向量化”。

一个系统的版本可以是:

  • main
    • module1@main:commit_1
    • module2@main:commit_x
    • ...
  • dev
    • module1@dev:commit_1
    • module2@dev:commit_x
    • ...
  • project_1
    • module1@projoect_1:commit_1
    • module2@projoect_1:commit_x
    • ...

分层系统的分支管理

如果系统内又做了分层,分为 base / app 两层,版本管理开始“树化”

一个分层的系统的版本可以是:

  • main
    • base
      • base_module1@main:commit_nn
      • base_module2@main:commit_mm
    • app
      • module1@main:commit_1
      • module2@main:commit_x
      • ...
  • dev
    • base
      • base_module1@dev:commit_nn
      • base_module2@dev:commit_mm
    • app
      • module1@dev:commit_1
      • module2@dev:commit_x
      • ...
    • ...
  • project_1
    • base
      • base_module1@project_1:commit_nn
      • base_module2@project_1:commit_mm
    • app
      • module1@project_1:commit_1
      • module2@project_1:commit_x
      • ...
    • ...

分层系统的分支管理困难根源

在分层的系统级分支管理上,如果严格遵守下面的分支管理策略,会简化非常多工程上的工作。

  • 定义 system_main 代表上面的分层系统的 main 分支
  • 定义 system_dev 代表上面的分层系统的 dev 分支
  • 定义 system_project 代表上面的分层系统的 feature 分支。

那么如果系统层上总是能从 dev->main->project 单线Pull-request 的话,系统的维护会向一个模块的分支管理一样简单。

但是,实际上不会发生这种事,实际上,在模块内,模块的开发是这样的:

  • 有一个 dev 分支
  • dev 分支的开发会往 main 合并
  • 如果有某个项目需求,会从 main 拉出一个 project_1 分支,然后,后续 project_1 上的修改要经过耗时更久的周期开发,满足 project_1 上的需求,并且它增长的commit会一直应用到 system_project_1 的commit里。与此同时, dev->main的主版本也在增长。

经过几个版本后,就会面临模块的 project_1 分支和 dev/main 分支的巨大差异,难以做分支的管理。

这是一个问题,如何在模块级别解决呢?

根本问题在于,模块级别要保持单线条,模块级别无论如何都坚持不分裂版本,坚持保持:
feature->dev->main 分支。

在system 级别,应该总是:

  • system_dev: 采用模块的 dev 分支。
  • system_main: 采用模块的 main 分支。
  • system_project: 采用模块的 main 分支!!!

那么,如何解决 system_project 上的「项目级」特殊需求呢?

答案是:没有特殊需求,所有需求都应该在 dev->main 上直接提供,system_project 只是在模块的 main 分支上,apply 了一组配置,这组配置是功能的开关。

事实上有些模块就是这么做的。而有些模块则版本之间差异很大,这实际上造成了分支的不一致,从而导致工程上的各种重复工作,例如在 main 上获得了好的工程指标,在project上滞后工程指标差,同时有巨大的同步压力。

核心就是:模块级别永远不分裂版本,保持单线条分支迭代: feature->dev->main

这是一个问题,如何在系统级别解决?

在系统级,不要让模块自由配置分支的名字,坚持以固化的分支名字来组织系统:

system_dev: 只装配每个模块的名字为 dev 的分支,部分同一个仓库分离出的可以加前缀:例如 xxx/dev,但是必须是这样命名的分支。门禁上直接禁止其他名字分支名字在系统级配置里出现。

同理,system_main: 只装配每个模块名字为 main 的分支。

现在,system_project_1: 只装配每个模块名字为 main 的分支。但是应用了一组预定义的「项目配置」。

system_main 和 system_project 都用的是模块的 main 分支,但是每个模块的commit 可能不同,但是system_project里的模块 commit 一定旧于 system_main 里的模块 commit。也就是说 system_project 里的模块 commit 一定是曾经出现在某一个版本 system_main 里的 commit。 这就倒逼了 模块功能发布到 project,一定经历了system_dev 系统,经历了 system_main 系统,最后发布到了 system_project。

这是一个问题,如何解决迭代速度问题?

这样的系统级分支管理,挑战是如何保证迭代速度,模块不能再直接从模块 commit 提交到 system_project。那就是要求 system_dev -> system_main -> system_project 的迭代非常快速。解决好这个迭代速度就会是工程上的核心水平构建。

但是一旦成功,收益将会是巨大的:所有的工程指标,只需要在 dev->main 上做一次。这是一个工程算法复杂度问题。

--end--

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章