版本控制基础:Git工作流程,分支策略,代码提交规范

说到 CI/CD,版本控制就是地基。地基不稳,后面所有自动化都是空中楼阁。我刚开始带团队时,就吃过分支混乱的亏——三个开发在同一个分支上改代码,合并时冲突多到让人崩溃。那次之后,我才认真把 Git 流程和分支策略理清楚。今天这一讲,咱们就聊聊这三块:工作流程怎么走,分支怎么分,提交信息怎么写。

1. Git 工作流程:从本地到远程

很多新手以为 Git 就是 git add、git commit、git push 三步走,其实漏掉了最关键的一步:拉取最新代码。我的习惯是每天上班第一件事先 git pull,确保本地分支是干净的。

典型的 Git 工作流分四层:

  1. 工作区(Working Directory)——你实际编辑文件的地方。
  2. 暂存区(Staging Area / Index)——准备提交的快照。
  3. 本地仓库(Local Repository)——已经提交的历史记录。
  4. 远程仓库(Remote Repository)——团队共享的代码中心。

每次修改的流转路径是:

工作区修改 → git add → 暂存区 → git commit → 本地仓库 → git push → 远程仓库

说实话,很多人觉得 git add 这一步多余,直接 commit 不行吗?我以前也这么想,直到有一次改了十几个文件,但只想提交其中三个 bugfix,才发现暂存区有多好用。它让你能精细控制每一次提交的内容。

还有一个常见误区:git pull 不是 git fetch + git merge?没错,git pull 默认执行 merge,如果团队用了 rebase 策略,建议显式用 git pull --rebase,让历史更线性。我个人更倾向 rebase,因为合并提交记录看起来很干净。

💡 技巧:如果你在 feature 分支上开发,每天至少 push 一次到远程,并且用 git status 检查当前状态。我见过太多人连续工作三天不 push,最后电脑坏了,代码全丢。

2. 分支策略:Git Flow vs Trunk Based

分支策略决定了团队协作的节奏。目前最主流的是两套:Git Flow 和 Trunk Based Development(主干开发)。我两个都实际用过,各有利弊。

维度 Git Flow Trunk Based
常用分支 master, develop, feature, release, hotfix main(或 trunk),短期 feature 分支
分支生命周期 长期稳定,feature 分支常存活几周 分支存活不超过 2 天
冲突频率 较低,但合并时容易大冲突 较高,但冲突范围小,随时解决
适用场景 版次发布间隔长、需要严格 release 管理的项目 持续交付、微服务、快速迭代团队
CI/CD 复杂度 高,需要多套流水线 低,主干一条流水线打天下

我的看法:如果你在做 SaaS 产品,每天要上线多次,Trunk Based 才是正解。Git Flow 更适合传统软件,比如一年发两版那种。我在前公司用过 Git Flow,每次 release 分支合并完,测试、修复、再合并,周期拉得很长。后来切换到 Trunk Based,配合特性开关,上线效率翻了一倍。

⚠️ 注意:Trunk Based 要求开发者必须频繁合并到主干(至少每天一次),并且要有足够的自动化测试覆盖。如果你团队测试覆盖率低于 60%,我建议还是先别用 Trunk Based,否则频繁合并会变成灾难。

另外要提一下分支命名规范。我团队统一用:

feature/xxx     —— 新功能
bugfix/xxx      —— 线上 bug 修复
hotfix/xxx      —— 紧急修复(直接基于 master)
release/xxx     —— 发布候选

不要起类似 test-1、dev-zhangsan 这种名字,几个月后你自己都看不懂。

3. 代码提交规范:写好 commit message

提交信息是代码的“注释中的注释”。我见过最离谱的 commit message 是 fix、update、111,甚至 asdf。这种信息对代码审查和版本回退毫无价值。

行业通用的是 Conventional Commits 规范。格式如下:

<type>(<scope>): <description>

[optional body]

[optional footer]

常用的 type:

  • feat:新功能
  • fix:bug 修复
  • docs:文档变化
  • style:代码格式(不影响功能)
  • refactor:重构
  • test:测试添加或修改
  • chore:构建过程或辅助工具变动

举个例子:

feat(login): add OAuth2 support for Google login

- Implement OAuth2 flow with Google API
- Add redirect URI configuration in env
- Update user model with provider field

Closes #123

我记得有一次,生产环境出了严重 bug,需要回退到三天前的版本。因为 commit history 乱七八糟,我们花了整整两个小时才找到正确的提交点。那次之后,我强制全团队开启 commitlint + husky,不符合规范的提交直接不让 push。

🚫 避坑指南:我曾经因为 commit message 用中文写了「修复登录按钮样式」,结果 CI 工具解析失败,自动生成 changelog 出来一堆乱码。建议 body 和 footer 用英文,description 可以中英混用,但最好统一用英文,配合国际团队。

4. 实战要点与避坑总结

  • 先 pull 再 push:推送前确保本地与远程无冲突。我习惯 git pull --rebase。
  • commit 粒度要小:每次提交只做一件事。比如修复一个 bug、添加一个函数。不要出现“提交了20个文件,改了十几处不相关的东西”。
  • 分支命名加 jira 编号:比如 feature/JIRA-123-user-login,方便追踪。
  • 使用 .gitignore:别把 node_modules、.env、编译产物推到仓库。我在面试时遇到过候选人的仓库里塞了 500MB 的日志文件,一看就是没配 .gitignore。
版本控制基础 · 知识体系 版本控制基础 Git 工作流程 分支策略 代码提交规范 工作区 暂存区 本地仓库 远程仓库 Git Flow Trunk Based master/develop feature/release 短期分支 + 特性开关 Conventional Commits commitlint + husky type(scope): desc feat/fix/docs/refactor 核心原则 频率高 → 粒度小 → 自动化检查 → 团队统一规则

最后说一句:版本控制不是工具问题,是习惯问题。你和团队约定好规则,再用自动化去强制执行,后面 CI/CD 才能跑得顺。下一个章节,咱们要深入到流水线里,看看每个阶段到底该做什么。