Git 提交规范详解
Git 提交规范(Commit Convention)是团队协作中保持代码历史清晰、可追溯的重要实践。以下是业界广泛采用的 Conventional Commits 规范的详细介绍。
提交信息的基本结构
一条标准的 Git Commit Message 由三部分组成:
<type>(<scope>): <subject>
// 空行
<body>
// 空行
<footer>
| 组成部分 | 是否必填 | 说明 |
| type | 必填 | 提交类型,描述本次变更的类别 |
| scope | 选填 | 影响范围,标明修改涉及的模块或组件 |
| subject | 必填 | 简短描述,概述本次变更内容 |
| body | 选填 | 详细描述,解释变更的动机、背景、具体内容 |
| footer | 选填 | 脚注,关联 Issue、标注 Breaking Change 等 |
Type(提交类型)详解
Type 是提交规范的核心,用于快速标识本次提交的意图:
| Type | 说明 | 示例场景 |
| feat | 新功能(feature) | 新增用户注册功能 |
| fix | 修复 Bug | 修复登录页面崩溃问题 |
| docs | 文档变更 | 更新 README、API 文档 |
| style | 代码格式调整(不影响逻辑) | 缩进、空格、分号、换行等 |
| refactor | 代码重构(既非新功能也非修复) | 重构数据处理模块 |
| perf | 性能优化 | 优化首页加载速度 |
| test | 测试相关 | 新增单元测试、修复测试用例 |
| build | 构建系统或外部依赖变更 | 升级 webpack、修改 npm scripts |
| ci | CI/CD 配置变更 | 修改 GitHub Actions、Jenkins 配置 |
| chore | 其他杂项(不修改源码或测试) | 更新 .gitignore、升级开发依赖 |
| revert | 回滚之前的提交 | 回滚某次错误合并 |
各部分编写规则
Subject(简短描述)
- 不超过 50 个字符(英文)或 25 个汉字
- 使用祈使语气,如 "add"、"fix"、"update"(英文场景)
- 首字母小写,结尾不加句号
- 描述 做了什么,而非怎么做的
# ✅ 正确
feat(auth): add OAuth2.0 login support
fix(cart): resolve item count display error
# ❌ 错误
feat(auth): Added OAuth2.0 login support. ← 大写开头 + 句号
fix: bug fix ← 描述不清晰
Body(正文)
- 与 subject 之间必须空一行
- 解释 为什么 做这个变更,以及 做了什么
- 每行不超过 72 个字符
- 可以使用列表形式组织多个变更点
fix(payment): resolve duplicate charge issue
Previously, when the network timed out during payment processing,
the retry mechanism would send a second charge request without
checking the status of the first one.
This commit adds an idempotency key to payment requests to prevent
duplicate charges. The key is generated based on order ID and
timestamp.
Footer(脚注)
脚注通常用于两种场景: 场景一:关联 Issue / 任务
feat(user): add email verification flow
Closes #123
Refs #456, #789
场景二:标注 Breaking Change(破坏性变更)
refactor(api): restructure user endpoint response
BREAKING CHANGE: The `user` endpoint now returns a nested `profile`
object instead of flat fields. Clients must update their parsing
logic to handle the new structure.
Before: { "name": "John", "age": 30 }
After: { "profile": { "name": "John", "age": 30 } }
示例
示例 1:简单的 Bug 修复
fix(login): correct password validation regex
The previous regex did not allow special characters in passwords,
causing users with complex passwords to fail login.
Closes #1024
示例 2:带 Breaking Change 的功能变更
feat(api)!: migrate authentication from JWT to OAuth2
Migrated the entire authentication system from self-managed JWT
tokens to OAuth2 with third-party providers.
- Added Google and GitHub as identity providers
- Removed custom token generation logic
- Updated middleware to validate OAuth2 tokens
- Added token refresh mechanism
BREAKING CHANGE: All API consumers must update their authentication
flow to use OAuth2 tokens. JWT tokens will no longer be accepted
after v3.0 release.
Refs #2048, #2050
示例 3:日常维护
chore(deps): upgrade eslint from 8.x to 9.x
工具链支持
规范的价值在于可以通过工具自动化执行和利用:
| 工具 | 用途 | 说明 |
| commitlint | 提交信息校验 | 在 git hook 中自动检查 commit message 是否符合规范 |
| commitizen (cz-cli) | 交互式提交 | 通过命令行引导开发者按模板填写提交信息 |
| husky | Git Hooks 管理 | 配合 commitlint 在 commit-msg 钩子中执行校验 |
| standard-version / release-please | 自动版本发布 | 根据 commit type 自动生成 CHANGELOG 和语义化版本号 |
| semantic-release | CI/CD 自动发版 | 全自动分析提交、确定版本号、发布包 |
语义化版本号的自动推导
Conventional Commits 最重要的价值之一是可以自动推导语义化版本号(SemVer):
| Commit Type | 版本影响 | 示例 |
fix | PATCH 版本升级 | 1.0.0 → 1.0.1 |
feat | MINOR 版本升级 | 1.0.0 → 1.1.0 |
任何 type + BREAKING CHANGE | MAJOR 版本升级 | 1.0.0 → 2.0.0 |
docs / style / chore 等 | 不触发版本升级 | — |