3、版本控制策略:Git Flow、Trunk Based Development 在座舱项目中的应用

版本控制这事儿,说白了就是团队协作的「交通规则」。没有规则,大家乱改一气,合并时就是一场灾难。我在座舱项目里见过太多次了——几个人同时改同一个模块,最后 merge 出来一堆冲突,光解决冲突就花掉半天。

座舱软件有个特点:迭代快、分支多、集成频繁。你想想看,一个座舱项目往往同时有仪表、中控、HUD、语音助手等多个模块在并行开发。选错分支策略,CI 流程根本跑不起来。

3.1 两种主流策略:Git Flow vs Trunk Based

先看一张对比图,帮你快速建立整体认知。

Git Flow vs Trunk Based 对比 Git Flow master(生产) develop(开发) release/1.0 feature/xxx hotfix/1.0.1 feature/yyy 分支多,管理成本高 适合大型、长期项目 发布节奏可控 Trunk Based main(主干) 短分支A 短分支B 短分支C 短分支D 分支少,合并频繁 适合快速迭代 CI 集成压力大

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 分支存活时间太长,有的甚至超过两周。代码差异太大,合并时各种冲突。

我的建议:如果团队规模超过 20 人,且发布周期在 2 周以上,Git Flow 是稳妥的选择。但一定要控制 feature 分支的存活时间,最好不超过 3 天。

3.3 Trunk Based Development:座舱 CI 的「加速器」

Trunk Based 的核心思想很简单:所有开发者都往主干(main)上提交,分支存活时间不超过 1 天。说白了,就是「小步快跑,频繁集成」。

座舱项目为什么适合 Trunk Based?因为座舱的迭代节奏太快了。今天加一个语音指令,明天改一个 UI 布局,后天修一个蓝牙连接 bug。如果用 Git Flow,光分支管理就够你受的。

Trunk Based 的典型工作流:

  1. 从 main 拉一个短分支(比如 feature/bt-fix)
  2. 在本地开发、测试
  3. 提交代码,触发 CI 流水线
  4. CI 通过后,合并回 main
  5. 删除短分支

整个流程控制在 1 天内。如果 CI 失败,要么立即修复,要么回退提交。

注意:Trunk Based 对 CI 的要求极高。每次提交都必须通过编译、单元测试、静态检查。如果 CI 跑 30 分钟,那开发者就得等 30 分钟。我曾经在一个项目里把 CI 从 45 分钟优化到 8 分钟,才真正跑通 Trunk Based。

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 的元素。别一开始就搞复杂了,否则团队会累死。