3. Git基础操作:从初始化到规范提交
好,咱们今天聊聊Git最基础的操作。说实话,我见过太多嵌入式工程师把Git当“备份工具”用——每天下班前commit一下,完事。这其实挺可惜的。Git真正的威力,在于它能让你的版本管理变得像精密仪器一样可控。
我个人习惯,在开始一个新嵌入式项目时,第一件事就是初始化Git仓库。别等到代码写了一半才想起来版本控制,那时候已经晚了。
3.1 git init 与 git clone:两种开始方式
git init 是在本地创建一个全新的仓库。适合你从零开始写项目。
cd my_embedded_project
git init
执行完这条命令,当前目录下会多出一个 .git 文件夹。嗯,别手贱去删它,那是Git的心脏。
git clone 则是从远程复制一个已有仓库到本地。我在接手团队遗留项目时经常用这个。
git clone https://github.com/example/stm32-firmware.git
这里有个小坑:嵌入式项目往往包含大尺寸的二进制文件(比如芯片的固件库、编译中间产物)。我曾经克隆一个仓库,结果发现下载了2个多G——后来才知道,有人把编译生成的 .hex 文件也提交上去了。所以,后面我们会讲 .gitignore 怎么配置,提前规避这类问题。
3.2 git add 与 git commit:把代码“装进”版本库
很多新手搞不清 add 和 commit 的关系。我打个比方:git add 是把文件放进“待提交区”(暂存区),git commit 才是正式拍照存档。
# 添加单个文件
git add main.c
# 添加所有改动(慎用!)
git add .
# 提交并写信息
git commit -m "fix: 修复UART接收缓冲区溢出问题"
我个人建议,尽量别用 git add . 一把梭。为什么?因为有时候你改了几个文件,但只想提交其中一部分。用 git add 逐个添加,能让你更清楚自己在做什么。
git add -p。它会逐块询问你是否要暂存。这个功能我在调试嵌入式驱动时经常用。
3.3 git status 与 git log:随时掌握仓库状态
git status 是我用得最频繁的命令,没有之一。每次提交前,我都会先跑一遍,看看哪些文件改了、哪些还没跟踪。
git status
输出会告诉你三件事:
- 已暂存(Staged)—— 准备提交的
- 已修改未暂存(Modified)—— 改了但还没add的
- 未跟踪(Untracked)—— 新文件,Git还没管它
git log 则是查看提交历史。我习惯加上 --oneline 参数,让输出更简洁。
git log --oneline -5
这会显示最近5次提交,每条一行。你想想看,如果每次提交信息都写得乱七八糟,那这个log基本就没法看了。所以,提交信息的规范写法,我们后面重点讲。
3.4 git diff:看看你到底改了啥
有时候你改了一堆代码,但忘了具体改了哪些地方。这时候 git diff 就派上用场了。
# 查看未暂存的改动
git diff
# 查看已暂存的改动(跟上次提交比)
git diff --staged
我记得有一次,同事说“我就改了一行配置”,结果我一看diff,他改了整整一个头文件。所以,提交前用 git diff --staged 检查一下,能避免很多乌龙。
3.5 .gitignore 文件配置:别把垃圾也提交了
嵌入式项目里,有很多文件是不应该进版本库的:
- 编译产物:.o、.hex、.bin、.elf
- IDE配置文件:.idea、.vscode、*.uvguix.*
- 临时文件:*.log、*.bak、*.swp
- 第三方库的二进制包
一个典型的嵌入式项目 .gitignore 长这样:
# 编译输出
build/
*.o
*.hex
*.bin
*.elf
*.map
# IDE配置
.idea/
.vscode/
*.uvguix.*
# 系统文件
.DS_Store
Thumbs.db
# 日志
*.log
git rm --cached 先把它从跟踪列表里移除。
3.6 提交信息的规范写法:让历史可读
这是很多嵌入式工程师容易忽略的地方。我见过太多“update”、“fix bug”、“改了点东西”这样的提交信息。说实话,三个月后你自己都看不懂当时改了啥。
我推荐使用 Conventional Commits 规范,格式如下:
<type>: <简短描述>
<详细说明(可选)>
常用的 type 包括:
| 类型 | 含义 | 嵌入式场景举例 |
|---|---|---|
| feat | 新功能 | feat: 添加SPI Flash驱动 |
| fix | 修复bug | fix: 修复看门狗超时导致系统重启 |
| docs | 文档 | docs: 更新I2C通信协议说明 |
| refactor | 重构 | refactor: 重构GPIO初始化代码 |
| perf | 性能优化 | perf: 优化ADC采样率,降低CPU占用 |
| test | 测试 | test: 添加UART回环测试用例 |
举个例子,一个规范的提交信息:
fix: 修复CAN总线在高速率下丢帧问题
问题原因:接收FIFO溢出时未及时清空标志位
解决方案:在中断服务函数中增加FIFO溢出检测与恢复逻辑
影响范围:仅影响CAN2通道,CAN1不受影响
3.7 嵌入式场景下的Git操作建议
最后,分享几个我在嵌入式项目中积累的小习惯:
- 每次提交只做一件事。 修复bug就只提交bug修复,不要混着加新功能。这样万一要回退,不会牵连其他改动。
- 提交前编译一下。 我见过有人提交了编译不过的代码,结果整个团队都被卡住。养成习惯:commit前先
make clean && make。 - 二进制文件单独管理。 芯片的固件库、工具链这些大文件,别往Git里塞。用包管理器或者单独的文件服务器管理。
- 分支命名要有意义。 比如
fix/can-bus-overflow、feature/adc-dma-support,别用test1、new_branch这种。
好了,Git基础操作就讲到这里。下一章我们会聊分支管理——说白了,就是怎么让多个人同时开发,还不打架。