版本控制与分支策略:Git Flow 与 Trunk Based 的选择
嵌入式项目的版本控制,说白了就是给代码上「保险」。我见过太多团队,代码乱成一锅粥,最后连哪个版本能跑都不知道。今天咱们聊聊分支策略——Git Flow 和 Trunk Based,到底怎么选。
两种主流分支模型
先看个对比表格,心里有个底:
| 特性 | Git Flow | Trunk Based |
|---|---|---|
| 分支数量 | 多(develop、feature、release、hotfix) | 少(主分支 + 短期特性分支) |
| 发布频率 | 低(周/月级) | 高(天/小时级) |
| 适合场景 | 硬件依赖强、发布周期固定 | CI/CD 成熟、快速迭代 |
| 合并复杂度 | 高(长期分支容易冲突) | 低(频繁合并,冲突少) |
| 嵌入式适配度 | ★★★★☆ | ★★★☆☆ |
Git Flow:嵌入式项目的「老黄牛」
我个人习惯在固件版本迭代慢、硬件平台固定的项目里用 Git Flow。为什么?因为嵌入式开发有个痛点——硬件依赖。
你想想看,一个功能写好了,但硬件还没回来。这时候 feature 分支就派上用场了。我在一个车载项目里遇到过:MCU 换型号,底层驱动全部重写。如果用 Trunk Based,主分支天天坏,CI 根本跑不过。Git Flow 的 develop 分支给了我们缓冲期,等硬件稳定了再合并。
核心分支结构:
- master:只放发布过的版本,每个 commit 对应一个 Release
- develop:日常开发集散地,所有 feature 往这合
- feature/*:新功能开发,从 develop 拉,合回 develop
- release/*:发布前准备,修 bug、改文档,合回 master 和 develop
- hotfix/*:线上紧急修复,从 master 拉,合回 master 和 develop
Trunk Based:CI/CD 的「加速器」
如果你的 CI/CD 流水线足够成熟,测试覆盖率够高,Trunk Based 会让你爽到飞起。我建议在原型验证阶段用这个模式——代码改得快,反馈也快。
Trunk Based 的核心就一句话:所有人往主干合,每天至少合一次。听起来简单,做起来难。我曾经在一个 IoT 项目里强推 Trunk Based,结果第一天 CI 就红了 8 次。为什么?因为嵌入式代码的编译时间长,单元测试跑得慢。
我的经验:Trunk Based 要想在嵌入式项目里落地,必须做到三点:
- 编译时间控制在 5 分钟内(用增量编译 + 分布式构建)
- 单元测试覆盖核心逻辑(驱动层用模拟器跑)
- 特性开关(Feature Toggle)要到位,没完成的功能直接关掉
怎么选?看这张流程图
代码审查与门禁机制
分支策略定好了,代码怎么进来?靠审查和门禁。我见过最惨的一次:有人把调试用的 printf 直接提交到 master,结果产线刷了固件,控制台疯狂打印日志,把 Flash 写坏了。
从那以后,我定了几条铁律:
门禁机制清单(MR 必须通过):
- 静态检查:MISRA-C 规则扫描,违规数必须为 0
- 编译检查:所有目标平台(ARM、RISC-V、Xtensa)全部通过
- 单元测试:新增代码覆盖率 ≥ 80%,核心模块 ≥ 90%
- 集成测试:至少通过冒烟测试用例集
- 代码审查:至少 2 个 Reviewer 批准,且 Reviewer 不能是作者
代码审查我建议用「小步提交」原则。每次 MR 不要超过 200 行,超过就拆。为什么?因为人一次看 200 行代码还能保持清醒,看 2000 行就只想点「批准」了。
我的审查习惯:
- 先看测试代码,再看业务代码——测试写得好,代码一般不会差
- 重点关注边界条件、中断上下文、内存操作
- 遇到「魔法数字」必须问清楚,不能放过
- Review 评论用「建议」语气,别用「你错了」
标签与 Release 管理
标签是版本控制的「锚点」。没有标签的仓库,就像没有路标的迷宫。我建议用语义化版本号:
vMAJOR.MINOR.PATCH-预发布标识+构建元数据
示例:
v2.1.0-rc.1+build20240315
v2.0.0
v1.3.2-hotfix.1
嵌入式项目里,标签还要带上硬件信息:
| 标签格式 | 含义 | 示例 |
|---|---|---|
| v{major}.{minor}.{patch} | 正式发布 | v3.1.0 |
| v{major}.{minor}.{patch}-rc.{n} | 候选版本 | v3.1.0-rc.2 |
| v{major}.{minor}.{patch}-{hw} | 指定硬件平台 | v3.1.0-stm32f4 |
| v{major}.{minor}.{patch}-hotfix.{n} | 紧急修复 | v3.0.1-hotfix.1 |
Release 管理我推荐用 GitLab Release 或 GitHub Release,配合 CI 自动生成 changelog。每次打标签时,CI 自动做三件事:
- 编译所有目标固件
- 运行全量回归测试
- 生成 Release Notes(从 commit message 提取)
我曾经踩过的坑:
- 标签打了但没推远端,同事拉不到,白忙活半天
- Release Notes 用手写,漏了关键变更,产线刷错固件
- hotfix 标签没合并回 develop,下次发布又把 bug 带出来了
现在我的流程是:标签必须由 CI 自动打,人工只负责确认版本号。Release Notes 从 commit 自动生成,再人工审核补充。
嗯,版本控制这件事,说难不难,说简单也不简单。关键是形成习惯,让流程成为肌肉记忆。下次咱们聊聊 CI 流水线怎么搭,那才是真正让分支策略发挥价值的地方。