构架(1): 再论分支管理问题。
无论系统怎么组织,只要发生如下问题,工程上就会非常费劲:
- 一个叶子结点的模块,在不同的系统集成里集成叶子结点模块的不同分支,这些分支之间代码差异很大。
单模块的分支管理
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
- ...
- base
- dev
- base
- base_module1@dev:commit_nn
- base_module2@dev:commit_mm
- app
- module1@dev:commit_1
- module2@dev:commit_x
- ...
- ...
- base
- 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
- ...
- ...
- base
分层系统的分支管理困难根源
在分层的系统级分支管理上,如果严格遵守下面的分支管理策略,会简化非常多工程上的工作。
- 定义 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--
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix