第四章:源码管理策略——分支模型、代码审查与版本规范
聊到源码管理,很多团队其实只用了 Git 的皮毛。说白了,就是把代码 push 上去,大家各改各的。但真正到了嵌入式固件开发,你会发现分支策略选错了,后面全是坑。我个人习惯把源码管理比作「交通规则」——没有规则,大家都能开,但早晚堵死。
4.1 分支模型:Git Flow 还是 Trunk Based?
先说说两种主流模型。Git Flow 适合大型、多版本并行的项目。Trunk Based 则更适合快速迭代、持续集成的场景。
Git Flow 的核心结构:
- master:只存发布过的稳定版本
- develop:日常开发的主线
- feature/*:新功能分支,从 develop 拉出
- release/*:预发布分支,用于最后测试和修 bug
- hotfix/*:紧急修复,直接从 master 拉
我在项目中遇到过一个问题:团队用了 Git Flow,但 release 分支长期不合并,导致 develop 和 master 差异巨大。最后发布时,合并冲突修了整整两天。所以我的建议是——Git Flow 虽好,但别滥用。如果你的团队只有 3-5 人,产品迭代周期短,Trunk Based 可能更合适。
Trunk Based 的要点:
- 所有开发者都在 main 分支上工作
- 分支存活时间不超过一天
- 通过特性开关(Feature Toggle)控制未完成的功能
我的经验:嵌入式固件开发中,我倾向于 Trunk Based + 短特性分支。因为固件通常需要频繁的集成测试,分支太多会导致测试覆盖不全。你想想看,一个 bug 在 feature 分支上躺了两周,合并到 main 时才发现,那代价就大了。
4.2 代码审查流程:不只是走形式
代码审查(Code Review)在很多团队里变成了「点个赞就走」。但真正有效的审查,应该像法庭辩论一样——每个改动都要有理由。
我建议的审查流程:
- 提交前自检:开发者自己跑一遍静态分析、单元测试
- 创建 Pull Request:描述清楚改了啥、为什么改、影响范围
- 至少两人审查:一个熟悉业务,一个熟悉技术
- 自动化检查:CI 自动跑编译、测试、代码风格检查
- 合并策略:使用 Squash Merge 保持历史干净
避坑指南:我曾经见过一个团队,代码审查只看格式,不看逻辑。结果一个指针越界的 bug 在 review 时被放过去了,最后在产线上复现,损失不小。所以审查时,重点关注逻辑正确性和边界条件,别只盯着缩进和命名。
审查清单示例:
| 检查项 | 说明 |
|---|---|
| 逻辑正确性 | 算法是否合理?边界条件是否覆盖? |
| 内存安全 | 是否有内存泄漏?指针是否安全? |
| 可移植性 | 代码是否依赖特定硬件或编译器? |
| 测试覆盖 | 是否有对应的单元测试或集成测试? |
| 文档同步 | API 文档、注释是否更新? |
4.3 标签与版本号规范
版本号这东西,看着简单,但乱起来真要命。我见过有人用 v1.0-final-真的最终版-不改了.bin 这种命名……嗯,你懂的。
我推荐的版本号规范:
- 语义化版本(SemVer):
MAJOR.MINOR.PATCH - MAJOR:不兼容的 API 修改
- MINOR:向下兼容的功能新增
- PATCH:向下兼容的问题修复
对于嵌入式固件,我习惯加上硬件版本和构建号:
v1.2.3-hw2-b456
│ │ │ │ └── 构建号(CI 自动生成)
│ │ │ └────── 硬件版本
│ │ └────────── PATCH
│ └───────────── MINOR
└──────────────── MAJOR
注意:标签一定要和 Git commit 绑定。我曾经犯过一个错:手动在文件里改了版本号,但忘了打 Git 标签。结果后来查问题,根本不知道这个固件是从哪个 commit 编译出来的。所以,版本号必须通过 CI 自动打标签,别靠人工。
标签命名建议:
- 正式版:
v1.0.0 - 预发布版:
v1.0.0-rc.1 - 内部测试版:
v1.0.0-alpha.1
最后说一句:源码管理策略不是银弹。没有完美的模型,只有适合你团队的模型。关键是定下来就要严格执行,别今天 Git Flow,明天 Trunk Based,后天又改回 Git Flow。那样的话,再好的工具也救不了你。
总结一下:
- 分支模型选一个,坚持用
- 代码审查要深入,别走过场
- 版本号规范要统一,自动化打标签
做到这三点,你的源码管理至少不会拖后腿。