3. 版本控制入门
说实话,我见过太多嵌入式工程师在SDK开发中栽在版本控制上。
有人改了一周代码,发现改错了想回退,结果不会。有人把整个SDK仓库搞得一团糟,分支乱成一锅粥。还有人干脆不用版本控制,靠复制文件夹来备份——"v1、v2、v3_final、v3_final_真的不改了"。
嗯,这些坑我都踩过。今天咱们就把Git在SDK开发中的那点事说清楚。
核心观点:Git不是用来"存代码"的,它是用来"管理变化"的。SDK开发中,你管理的不是代码,而是整个生态系统的演进过程。
3.1 Git基础操作:够用就行
我不打算把Git的所有命令都讲一遍,那没意义。实际SDK开发中,你80%的时间只用那20%的命令。
日常三板斧:
git add—— 把改动放进暂存区git commit—— 把暂存区的内容打个快照git push—— 把本地提交推送到远程
我个人的习惯是:每次提交只做一件事。比如"修复了I2C驱动在高速模式下的时序问题",而不是"改了一些东西"。
我的小技巧:提交信息用英文写,但一定要说清楚"为什么改",而不是"改了啥"。比如"fix: adjust I2C timing for high-speed mode"比"update i2c driver"有用十倍。
还有一个命令我几乎天天用——git log --oneline --graph。它能让你一眼看清整个仓库的演进脉络。我曾经在排查一个SDK的bug时,就是靠这个命令发现某个提交意外引入了一个头文件冲突。
3.2 仓库管理:SDK不是普通项目
SDK开发和普通应用开发有个本质区别:SDK要同时维护多个硬件平台、多个工具链版本、多个内核版本。
你想想看,一个SDK仓库里可能同时有:
- ARM Cortex-M的BSP包
- RISC-V的启动代码
- X86的模拟器支持
- 三套不同的交叉编译工具链
这些东西全塞在一个仓库里?那不乱套才怪。
我推荐的做法是:
- 用子模块(submodule)管理独立的组件
- 用仓库模板统一初始化结构
- 用标签(tag)标记每个发布版本
举个例子,我参与过一个物联网SDK项目,仓库结构大概是这样的:
sdk-root/
├── .gitmodules # 子模块配置
├── bsp/ # 板级支持包(子模块)
├── middleware/ # 中间件(子模块)
├── tools/ # 工具链(子模块)
├── examples/ # 示例代码
├── docs/ # 文档
└── scripts/ # 构建脚本
每个子模块都有自己的仓库、自己的版本号、自己的维护者。这样改BSP的人不会影响到中间件,反之亦然。
注意:子模块有个坑——默认是"detached HEAD"状态。我曾经有同事在子模块里改了代码没提交,然后更新了父仓库,改动的代码直接丢了。嗯,血的教训。记得每次进子模块先 git checkout master。
3.3 分支策略:选对模型省一半力气
分支策略这东西,没有银弹。但SDK开发有个特点:长期维护 + 多版本并行。
我个人最推荐的是Git Flow的简化版:
| 分支类型 | 命名规则 | 用途 |
|---|---|---|
| 主分支 | master |
只放经过完整测试的发布版本 |
| 开发分支 | develop |
日常开发的主线 |
| 功能分支 | feature/xxx |
开发新功能,完成后合并到develop |
| 修复分支 | hotfix/xxx |
紧急修复线上问题,直接基于master |
| 发布分支 | release/vx.x |
发布前的最后准备,只修bug不加功能 |
为什么会这样设计?因为SDK的发布周期通常很长。比如一个版本发布后,客户可能用了一年才报bug。这时候你develop分支已经跑得很远了,不能直接把develop合并回去——那会把一堆新功能也带进去。
正确的做法是:从对应的release/v1.0标签创建hotfix分支,修完bug后合并回master和develop。
避坑指南:我曾经在一个SDK项目里,团队直接在master上开发,结果发布时发现master上有一半的功能还没测完。嗯,从那以后我坚持"master只放能用的代码"。
3.4 在SDK开发中如何使用Git
理论说完了,咱们来点实际的。SDK开发中Git到底怎么用?
场景一:给客户发一个SDK版本
- 从develop创建
release/v2.1分支 - 在这个分支上只修bug,不加新功能
- 测试通过后,合并到master
- 在master上打标签:
git tag -a v2.1.0 -m "SDK v2.1.0 release" - 把标签推送到远程:
git push origin v2.1.0
场景二:客户报了一个bug,需要紧急修复
- 从
v2.1.0标签创建hotfix/i2c-timeout分支 - 修完bug,提交
- 合并到master,打
v2.1.1标签 - 也合并到develop,保证develop也有这个修复
场景三:同时维护两个版本
比如客户A在用v2.1,客户B在用v2.0。这时候你需要两个长期分支:
master指向最新的v2.1.xv2.0.x分支专门维护v2.0版本
两个分支各自修各自的bug,互不干扰。
我的经验:别怕分支多。Git的分支本质上就是个指针,创建成本几乎为零。我见过一个SDK项目同时维护了5个版本分支,每个分支上还有hotfix和feature分支,加起来几十个分支。但只要命名规范、合并策略清晰,一点都不乱。
3.5 知识体系总览
下面这张图是我自己总结的SDK版本控制知识体系,你可以把它当成一个"速查地图":
这张图把今天讲的内容串起来了。左边是基础操作,中间是仓库管理,右边是分支策略,底部是实际应用场景。你每次遇到Git相关的问题,都可以回来看看这张图,找到对应的模块。
好了,Git在SDK开发中的用法就讲到这里。记住一句话:版本控制不是为了管代码,是为了管变化。你管好了变化,SDK的长期维护就不再是噩梦。
最后送大家一句话:Git本身不复杂,复杂的是人。定好规则、严格执行、定期复盘,比学一万个Git命令都管用。
可可精品资料库