3、版本控制入门:Git基础操作、仓库管理、分支策略、在SDK开发中如何使用Git

说实话,我见过太多嵌入式工程师在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版本

  1. 从develop创建release/v2.1分支
  2. 在这个分支上只修bug,不加新功能
  3. 测试通过后,合并到master
  4. 在master上打标签:git tag -a v2.1.0 -m "SDK v2.1.0 release"
  5. 把标签推送到远程:git push origin v2.1.0

场景二:客户报了一个bug,需要紧急修复

  1. 从v2.1.0标签创建hotfix/i2c-timeout分支
  2. 修完bug,提交
  3. 合并到master,打v2.1.1标签
  4. 也合并到develop,保证develop也有这个修复

场景三:同时维护两个版本

比如客户A在用v2.1,客户B在用v2.0。这时候你需要两个长期分支:

  • master 指向最新的v2.1.x
  • v2.0.x 分支专门维护v2.0版本

两个分支各自修各自的bug,互不干扰。

我的经验:别怕分支多。Git的分支本质上就是个指针,创建成本几乎为零。我见过一个SDK项目同时维护了5个版本分支,每个分支上还有hotfix和feature分支,加起来几十个分支。但只要命名规范、合并策略清晰,一点都不乱。

3.5 知识体系总览

下面这张图是我自己总结的SDK版本控制知识体系,你可以把它当成一个"速查地图":

SDK版本控制知识体系 基础操作 • git add / commit / push • git log --oneline --graph • git diff / git status • git stash 临时保存 • git reset / git revert 仓库管理 • 子模块 submodule • 仓库模板初始化 • 标签 tag 版本标记 • .gitignore 配置 • 远程仓库管理 分支策略 • master 主分支 • develop 开发分支 • feature/xxx 功能分支 • hotfix/xxx 修复分支 • release/vx.x 发布分支 SDK开发实践场景 场景1:发布版本 → release分支 + tag标记 场景2:紧急修复 → hotfix分支 + 合并回master/develop 场景3:多版本维护 → 多个长期分支并行 场景4:多人协作 → feature分支 + code review 场景5:客户定制 → 基于tag创建定制分支

这张图把今天讲的内容串起来了。左边是基础操作,中间是仓库管理,右边是分支策略,底部是实际应用场景。你每次遇到Git相关的问题,都可以回来看看这张图,找到对应的模块。

好了,Git在SDK开发中的用法就讲到这里。记住一句话:版本控制不是为了管代码,是为了管变化。你管好了变化,SDK的长期维护就不再是噩梦。

最后送大家一句话:Git本身不复杂,复杂的是人。定好规则、严格执行、定期复盘,比学一万个Git命令都管用。

可可精品资料库