3、版本控制策略:Git Flow、Trunk Based Development 在座舱项目中的应用
版本控制这事儿,说白了就是团队协作的「交通规则」。没有规则,大家乱改一气,合并时就是一场灾难。我在座舱项目里见过太多次了——几个人同时改同一个模块,最后 merge 出来一堆冲突,光解决冲突就花掉半天。
座舱软件有个特点:迭代快、分支多、集成频繁。你想想看,一个座舱项目往往同时有仪表、中控、HUD、语音助手等多个模块在并行开发。选错分支策略,CI 流程根本跑不起来。
3.1 两种主流策略:Git Flow vs Trunk Based
先看一张对比图,帮你快速建立整体认知。
3.2 Git Flow:适合座舱的「保守派」选择
Git Flow 有 5 种核心分支:master、develop、feature、release、hotfix。每个分支都有明确的职责。
| 分支类型 | 命名示例 | 生命周期 | 合并目标 |
|---|---|---|---|
| master | master | 永久 | — |
| develop | develop | 永久 | master |
| feature | feature/hmi-dark-mode | 开发完成即删除 | develop |
| release | release/2.3.0 | 发布后删除 | master + develop |
| hotfix | hotfix/2.2.1 | 修复后删除 | master + develop |
我在座舱项目里用过 Git Flow。当时团队 40 多人,分 6 个小组并行开发。每个 feature 分支独立开发,互不干扰。release 分支用来做最后的回归测试,hotfix 分支专门处理线上紧急问题。
但有个问题——分支多了,合并就成了噩梦。我记得有一次,一个 release 分支合并回 develop,光解决冲突就花了 3 天。为什么?因为 feature 分支存活时间太长,有的甚至超过两周。代码差异太大,合并时各种冲突。
3.3 Trunk Based Development:座舱 CI 的「加速器」
Trunk Based 的核心思想很简单:所有开发者都往主干(main)上提交,分支存活时间不超过 1 天。说白了,就是「小步快跑,频繁集成」。
座舱项目为什么适合 Trunk Based?因为座舱的迭代节奏太快了。今天加一个语音指令,明天改一个 UI 布局,后天修一个蓝牙连接 bug。如果用 Git Flow,光分支管理就够你受的。
Trunk Based 的典型工作流:
- 从 main 拉一个短分支(比如 feature/bt-fix)
- 在本地开发、测试
- 提交代码,触发 CI 流水线
- CI 通过后,合并回 main
- 删除短分支
整个流程控制在 1 天内。如果 CI 失败,要么立即修复,要么回退提交。
3.4 座舱项目中的实战选择
到底选哪个?我个人的经验是:看团队规模和发布节奏。
| 场景 | 推荐策略 | 原因 |
|---|---|---|
| 团队 < 10 人,周迭代 | Trunk Based | 分支少,集成快,适合快速验证 |
| 团队 10-30 人,双周迭代 | Git Flow 简化版 | 保留 develop 和 feature,去掉 release 分支 |
| 团队 > 30 人,月迭代 | Git Flow 完整版 | 需要严格的分支隔离和发布管理 |
| 多车型并行开发 | Git Flow + 环境分支 | 每个车型一个 release 分支,互不干扰 |
嗯,这里要注意一点。座舱项目往往涉及多个硬件平台(高通、瑞萨、MTK)。不同平台的代码可能有差异。我建议在 Trunk Based 的基础上,用编译宏或配置文件来区分平台,而不是用分支来区分。否则分支会爆炸。
3.5 避坑指南:我踩过的几个坑
我曾经在一个座舱项目里吃过亏,分享出来,你们别重蹈覆辙。
- 分支存活时间过长:feature 分支超过 5 天不合并,基本就是一颗定时炸弹。合并时冲突多到让人崩溃。
- CI 不跑全量测试:只跑增量测试,结果合并后全量编译失败。后来我强制要求每次提交都跑全量编译和核心测试。
- 没有代码审查:Trunk Based 模式下,代码审查容易被忽略。但越频繁的集成,越需要严格的 review。我建议至少 2 人 review 后才能合并。
- 忽略 hotfix 流程:线上出 bug 时,有人直接在 main 上改。结果下次发布时,hotfix 的代码被覆盖了。正确的做法是:从 master 拉 hotfix 分支,修复后合并回 master 和 develop。
核心原则:无论选哪种策略,都要保证 main/master 分支的代码始终是可发布状态。这是 CI 的底线,也是版本控制的底线。
3.6 一个实际的 Git Flow 示例
假设我们正在开发座舱的「蓝牙电话」功能。用 Git Flow 的流程是这样的:
# 1. 从 develop 拉 feature 分支
git checkout develop
git pull
git checkout -b feature/bluetooth-phone
# 2. 开发、提交
git add .
git commit -m "feat: add bluetooth phone dialer UI"
git push origin feature/bluetooth-phone
# 3. 开发完成,合并回 develop
git checkout develop
git pull
git merge --no-ff feature/bluetooth-phone
git push origin develop
# 4. 删除 feature 分支
git branch -d feature/bluetooth-phone
git push origin --delete feature/bluetooth-phone
# 5. 准备发布时,拉 release 分支
git checkout develop
git checkout -b release/2.3.0
git push origin release/2.3.0
# 6. release 分支上只修 bug,不添功能
# 7. 测试通过后,合并到 master 和 develop
git checkout master
git merge --no-ff release/2.3.0
git tag -a v2.3.0 -m "Release version 2.3.0"
git push origin master --tags
git checkout develop
git merge --no-ff release/2.3.0
git push origin develop
# 8. 删除 release 分支
git branch -d release/2.3.0
git push origin --delete release/2.3.0
如果是 Trunk Based,流程就简单多了:
# 1. 从 main 拉短分支
git checkout main
git pull
git checkout -b fix/bt-crash
# 2. 开发、提交、触发 CI
git add .
git commit -m "fix: resolve bluetooth crash on incoming call"
git push origin fix/bt-crash
# 3. CI 通过后,创建 PR,review 后合并
# 4. 删除短分支
git branch -d fix/bt-crash
git push origin --delete fix/bt-crash
你看,Trunk Based 的流程更短,但要求每个提交都是「可集成的」。如果 CI 跑不过,那就别合并。
3.7 小结
版本控制策略没有银弹。Git Flow 适合大型、多团队、长周期的座舱项目;Trunk Based 适合小团队、快速迭代的场景。我个人的建议是:从 Trunk Based 开始,如果发现分支管理压力大,再逐步引入 Git Flow 的元素。别一开始就搞复杂了,否则团队会累死。