3. 版本控制与分支策略
NVIDIA DRIVE 平台的软件栈通常由数百个仓库、上千个包和大量二进制资产组成,既有 C/C++ 源码、CUDA 内核、TensorRT 引擎,也有 DNN 权重、标定文件、地图切片和仿真回放数据。持续集成与回归测试能否稳定运行,首先取决于版本控制是否把“源码、二进制、配置、发布标签”四类对象管理清楚。本节围绕 Git 在大规模车载软件中的使用方式、Git LFS 对大文件的管理,以及分支模型与 DRIVE 发布周期的对齐展开。
一、为什么普通 Git 管不住 DRIVE 仓库
Git 的对象模型是内容寻址的,每次提交都会把变更文件压缩成 blob 存入 .git/objects,并保留完整历史。对文本源码这非常高效,但对动辄数百 MB 的 DNN 权重、几十 GB 的仿真数据集,会带来三个直接后果:克隆时间从分钟级膨胀到小时级;每次拉取都要传输历史版本;CI 节点磁盘被历史对象迅速占满。因此 DRIVE 工程实践中普遍采用“源码走 Git、大文件走 LFS、超大只读数据走制品库”的分层策略。
二、Git LFS 的工作机制与配置
Git LFS(Large File Storage)并不把大文件本体提交进 Git 历史,而是在仓库中保存一个约 130 字节的指针文件,真正的二进制内容存放在 LFS 服务器。克隆时先取指针,再按需下载对应对象。其关键配置如下:
# 1. 安装并初始化 LFS
git lfs install
# 2. 声明需要 LFS 管理的文件类型
git lfs track "*.onnx"
git lfs track "*.engine"
git lfs track "*.bin"
git lfs track "*.bag"
git lfs track "calib/**/*.yaml"
# 3. 确认 .gitattributes 已生成并提交
git add .gitattributes
git commit -m "chore: track large binaries with LFS"
# 4. 查看当前 LFS 跟踪与占用
git lfs ls-files
git lfs status
需要特别注意的是,.gitattributes 必须与文件一起提交,否则其他开发者克隆后不会触发 LFS 过滤。若某个大文件在启用 LFS 之前已被提交进历史,需要用 git lfs migrate import --include="*.onnx" 重写历史,这会改变提交哈希,必须与所有协作者协调,并在受控窗口内执行。CI 侧则应在流水线开始处执行 git lfs pull,并配置 LFS 缓存目录,避免每个 Job 重复下载同一权重。
三、分支模型与 DRIVE 发布周期的对齐
DRIVE 的发布节奏通常由整车项目节点驱动:内部迭代以周为单位,对外交付以季度或项目里程碑为单位。若直接套用标准 GitFlow,会出现 develop 与 release 长期分叉、回归基线难以复现的问题。更贴合车载软件的做法是“主干开发 + 发布分支 + 标签冻结”:
- main:始终可构建、可回归,对应每日集成基线,任何合并必须通过门禁。
- feature/*:功能开发分支,生命周期短,通常不超过两周,合并前必须 rebase 到最新 main。
- release/drive-<版本>:从 main 切出,进入冻结期,只接受缺陷修复,不再合入新功能。
- hotfix/*:针对已交付版本的紧急修复,修复后同时回合 main 与对应 release 分支。
- 标签:
drive-6.0.3-rc1、drive-6.0.3-ga,标签一旦打出即不可移动,作为回归测试与问题追溯的唯一锚点。
分支与发布周期的对齐关系可以用下图表示。图中横向为时间轴,纵向为分支层级,颜色区分开发、冻结、交付三种状态,箭头表示合并方向。
四、CI 与回归测试中的版本控制实践
在流水线中,版本控制策略直接影响回归结果的可复现性。建议遵循以下要点:
- 基线可追溯:每次回归测试记录 commit SHA、LFS 对象哈希、标签名三者组合,任何一次失败都能精确还原当时的代码与权重。
- 浅克隆 + LFS 按需拉取:CI 使用
git clone --depth 1 --filter=blob:none,配合git lfs pull --include="*.engine",只取当前构建需要的二进制,减少节点 IO。 - 分支保护:main 与 release/* 开启保护规则,禁止直接 push,必须通过 MR 且门禁(编译、单元测试、静态检查)全绿。
- 合并策略统一:feature 合入 main 使用 squash merge,保持主干历史线性;release 合回 main 使用 merge commit,保留发布边界。
- 标签签名:GA 标签使用 GPG 签名(
git tag -s),确保交付物来源可信。
五、常见问题与判断依据
当出现“克隆慢、CI 磁盘满、回归结果与本地不一致”时,可按以下顺序排查:先用 git lfs ls-files 确认大文件是否真正走 LFS;再用 git count-objects -vH 查看仓库体积,若 size-pack 异常大,说明历史中混入了大文件,需要 migrate;最后核对回归记录中的 commit SHA 与标签是否一致,若不一致则说明基线漂移,应重新冻结。判断标准很明确:同一标签在任意节点上应产生相同的构建输入哈希,否则版本控制策略尚未闭环。
综上,DRIVE 项目的版本控制不是简单的 Git 使用技巧,而是把源码、二进制、发布节奏三者绑定成可追溯、可复现的工程约束。只有分支模型与发布周期严格对齐,LFS 与制品库分工清晰,回归测试的结果才具备工程可信度。