3. 版本控制基础:Git核心概念在文档管理中的应用
说实话,我见过太多嵌入式团队在文档管理上吃过亏。有人用「最终版_v3_改」这种文件名,有人把文档存在微信聊天记录里。嗯,这些我都经历过。直到我把 Git 引入文档管理,才算是真正解脱了。
你可能会问:Git 不是给代码用的吗?用在文档上行不行?我告诉你,不仅行,而且非常合适。文档和代码本质上都是文本,Git 对文本的差异对比能力,简直就是为文档版本管理量身定做的。
核心观点:Git 不是代码的专利。架构文档、接口规范、需求说明,只要是文本格式,Git 都能管得服服帖帖。
3.1 仓库(Repository):文档的「家」
仓库就是 Git 的工作目录。你把文档放进去,Git 就开始盯着它。我个人习惯把每个嵌入式项目建一个独立的仓库,里面既放代码也放文档。这样架构文档和代码始终同步,不会出现文档改了但代码没改的尴尬。
仓库分两种:本地仓库和远程仓库。本地仓库在你电脑上,远程仓库在服务器上(比如 GitLab 或 Gitee)。我建议嵌入式团队一定要配一个私有的远程仓库,因为架构文档里经常涉及硬件接口细节,不适合公开。
我的建议:仓库根目录下建一个 docs/ 文件夹,里面按文档类型划分子目录。比如 docs/architecture/、docs/api/、docs/meeting/。这样结构清晰,找东西快。
3.2 提交(Commit):文档的「快照」
提交是 Git 最核心的操作。每次提交就是给当前所有文档拍一张快照。你改完一段架构描述,或者更新了一个接口定义,就做一次提交。
提交信息怎么写?我踩过坑。以前我写「更新文档」四个字,结果一周后自己都看不懂改了啥。后来我定了个规矩:提交信息必须说清楚「为什么改」和「改了哪」。
| 提交信息类型 | 反面例子 | 正面例子 |
|---|---|---|
| 架构变更 | 更新架构图 | 新增 CAN 总线驱动层架构,删除旧版轮询方案 |
| 接口修改 | 改接口 | SPI 通信接口增加超时参数,兼容 STM32F4 硬件限制 |
| 评审反馈 | 修改评审意见 | 根据评审意见修正内存管理章节:补充堆栈溢出场景 |
避坑指南:我曾经有一次提交了 200 个文件的改动,提交信息只写了「大更新」。后来想回退某个文档的改动,根本找不到对应版本。记住:一次提交只做一件事,提交信息要精确到文件名和改动内容。
3.3 分支(Branch):文档的「平行宇宙」
分支是 Git 最强大的功能之一。你可以把分支理解成文档的平行宇宙。主分支(main 或 master)放的是经过评审的正式版本,其他分支用来做实验、写草稿、或者并行开发不同模块的文档。
我在项目中常用的分支策略是这样的:
- main 分支:只放评审通过的正式文档。任何人不能直接往 main 上推代码,必须走合并请求(Merge Request)。
- develop 分支:日常开发中的文档草稿。团队成员在这里协作写文档。
- feature/xxx 分支:针对某个模块的文档。比如
feature/can-bus-arch专门写 CAN 总线架构文档。 - release/x.x 分支:发布前的文档冻结版本。这时候只改 bug,不加新内容。
你想想看,如果没有分支,几个人同时改一份架构文档,那不乱套了?分支让每个人在自己的空间里工作,最后再合并,互不干扰。
经验之谈:文档分支的生命周期应该比代码分支短。代码可能开发几个月,但文档分支建议不超过两周。拖太久,分支里的文档就和主分支脱节了,合并时全是冲突。
3.4 标签(Tag):文档的「里程碑」
标签就是给某个提交打上一个固定的名字。我通常用标签来标记文档的正式发布版本。比如架构文档评审通过后,打一个 v1.0.0 的标签。以后不管怎么改,都能快速回到这个版本。
标签和分支的区别在哪?分支会随着新提交移动,标签是固定的。说白了,标签就是书签,分支就是工作台。
| 特性 | 标签(Tag) | 分支(Branch) |
|---|---|---|
| 可变性 | 不可变,指向固定提交 | 可变,随新提交移动 |
| 用途 | 标记版本、里程碑 | 并行开发、功能迭代 |
| 命名规范 | v1.0.0、v2.1.0-rc1 | main、develop、feature/xxx |
| 文档场景 | 架构评审通过版、发布版 | 草稿、多人协作、模块开发 |
我的习惯:每次架构评审会结束后,如果文档有修改,就立刻打一个新标签。标签名用语义化版本号:v主版本.次版本.修订号。比如架构重构算主版本,新增一个模块算次版本,修个错别字算修订号。
3.5 四个概念的关系:一张图说清楚
这四个概念不是孤立的。我画了一张图,帮你理清它们之间的关系。
3.6 文档管理的 Git 工作流实战
光讲概念不够,我给你一个可以直接用的工作流。这是我目前在嵌入式项目中用的,效果不错。
- 初始化仓库:在项目根目录执行
git init,然后创建docs/文件夹。 - 创建主分支:默认的 main 分支只放评审通过的文档。第一次提交放一个 README.md,说明文档目录结构。
- 开发分支:从 main 创建 develop 分支,日常写文档都在 develop 上。
- 功能分支:如果需要写某个模块的架构文档,从 develop 创建
feature/模块名分支。 - 提交规范:每次修改后,用
git add 文件名精确添加文件,然后用git commit -m "类型: 描述"提交。 - 合并请求:功能分支写完后,发起合并请求到 develop。至少一个人评审后才能合并。
- 发布标签:develop 分支稳定后,合并到 main,然后打标签
v1.0.0。
我曾经踩过的坑:有次我直接在 main 分支上改文档,改到一半发现思路不对,想回退。但因为 main 分支被多人共用,回退影响了别人的工作。从那以后,我坚持「绝不在 main 上直接修改」的原则。main 只接受合并请求,不接受直接推送。
3.7 文档差异对比:Git 的杀手锏
文档管理最大的痛点是什么?是找不同。两个人改了同一份文档,到底改了哪?用 Git 的 git diff 命令,一目了然。
对于 Markdown 或 reStructuredText 这类纯文本格式的文档,Git 能精确到每一行的增删改。我经常在评审时用 git diff 查看两个版本的差异,比肉眼对比快十倍。
# 查看工作区和暂存区的差异
git diff docs/architecture/can-bus.md
# 查看两个提交之间的差异
git diff v1.0.0 v1.1.0 -- docs/
# 查看某个文件的历史修改
git log -p -- docs/architecture/can-bus.md
小技巧:如果文档是 Word 或 PDF 格式,Git 没法直接对比。我建议嵌入式团队的架构文档统一用 Markdown 格式。既能用 Git 对比,又能用 Pandoc 转换成 PDF 或 HTML,一举两得。
3.8 本章小结
Git 的四个核心概念——仓库、提交、分支、标签——在文档管理中各司其职。仓库是容器,提交是快照,分支是平行空间,标签是里程碑。把这四个概念用好,文档版本管理就不再是头疼的事。
记住一句话:文档和代码一样,都是需要版本管理的资产。别让你的架构文档变成「最终版_v3_改」那样的灾难。