Commit Message 规范的优势
Commit Message 是项目的“航行日志”。规范的提交记录能够:
- 提升可读性:让历史记录一目了然,无需阅读代码即可理解变更目的。
- 便于追溯:快速定位问题引入或修复的提交,支持自动化生成 CHANGELOG。
- 降低协作成本:Code Review 更高效,新人接手项目更顺畅。
- 过滤筛选:可通过
git log --grep快速筛选特定类型提交(如新功能、修复)。 - 关联 Issue:在 Footer 中自动关闭 Issue,实现代码与需求联动。
- 避免“考古” :清晰的提交记录让排查问题像看说明书,而不是考古现场。
业界最通用的规范是基于 Angular 提交规范 衍生的 Conventional Commits 规范。本文档在此规范基础上,结合团队实践进行了适当扩展(如增加了 to、sync、merge 等类型),以适应更丰富的协作场景。
Commit Message 标准结构
一个规范的提交信息包含三部分:标题行(必填)、主体内容(可选)、脚注(可选),各部分之间用空行分隔。
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
各部分说明
| 部分 | 要求与示例 |
|---|---|
| type | 必填,标识提交类型(如 feat、fix),全小写英文。 |
| scope | 可选,指定影响范围(模块/功能名,如 user、order、api)。无则省略括号。 |
| subject | 必填,简洁概括提交内容(50/100字符内)。使用祈使句,首字母小写,结尾不加标点。 |
| body | 可选,详细说明变更动机、实现逻辑、影响范围等。同样使用祈使句,可换行。 |
| footer | 可选,关联 Issue/需求 ID(如 Closes #123),或标注不兼容变更(BREAKING CHANGE: ...),或添加 [skip ci] 跳过 CI 构建。 |
注意:标题行建议不超过 50 个字符,任何一行不应超过 72 个字符,这是为了避免在终端或 Git 工具中自动换行影响可读性。部分团队可放宽至 100 字符,请根据实际情况统一。
Type 类型
| 类型 | 适用场景 | 示例 |
|---|---|---|
| feat | 新增功能(用户可感知的新能力、新接口、新页面) | feat(user): 支持手机号登录 |
| fix | 修复 Bug(逻辑错误、异常行为、崩溃等) | fix(order): 修复订单金额计算错误 |
| to | 只产生 diff 不自动修复问题,适用于多次提交的场景(最终修复时使用 fix) (此类型为团队扩展,不会出现在自动生成的 CHANGELOG 中) | to(login): 部分修复验证码问题 |
| docs | 仅修改文档(README、注释、接口文档,不涉及代码逻辑) | docs: 更新 API 接口说明 |
| style | 代码格式调整(缩进、空格、分号、命名规范,不改变代码逻辑) | style: 统一变量命名为小驼峰 |
| refactor | 重构代码(既不新增功能也不修复 Bug,如函数抽取、模块拆分) | refactor(api): 拆分用户模块接口逻辑 |
| perf | 性能优化(减少响应时间、降低内存占用、优化查询效率) | perf(list): 优化长列表渲染性能 |
| test | 新增或修改测试用例(单元测试、集成测试) | test(user): 新增登录流程测试 |
| build | 构建相关修改(依赖包更新、构建脚本、Docker 配置等) | build: 升级 requests 依赖到 2.31.0 |
| ci | CI/CD 配置修改(GitHub Actions、Jenkins 等) | ci: 添加自动化测试流程 |
| chore | 其他不影响代码逻辑的修改(删除无用文件、配置文件调整、日志格式修改等) | chore: 删除废弃的测试数据文件 |
| revert | 回滚之前的提交 | revert: feat(user): 回滚新增注册接口 |
| merge | 代码合并(团队扩展类型,用于标识合并提交) | merge: 分支 feature/login 合并到 dev |
| sync | 同步主线或分支的 Bug(团队扩展类型,常用于同步修复) | sync: 同步主线的支付模块修复 |
常用说明:
- 用户能感知的变化 →
feat- 预期行为未达成,修正后恢复正常 →
fix- 外部表现一致,内部结构优化 →
refactor- 性能提升 →
perf- 其他不影响生产逻辑的杂务 →
chore- 扩展类型
to、sync、merge需团队成员理解其特定语义,避免滥用。
scope 影响范围
scope 用于说明 commit 影响的范围,如模块名、功能名、目录名等。可按以下维度划分:
- 技术维度:
controller、service、dao、dto等(较少用,因一个提交可能涉及多个技术层) - 业务维度:
user(用户模块)、order(订单模块)、payment(支付模块)等(推荐)
示例:fix(order): 修复订单金额计算错误
若修改影响了多个 scope,可使用
*代替(团队约定)。如果希望 scope 也受到枚举约束,可在 commitlint 配置中增加scope-enum规则。
subject 简短描述
- 使用祈使句(“新增”而非“新增了”)
- 首字母小写(英文场景)或使用中文(推荐中文团队使用中文描述更清晰)
- 团队应统一语言:建议全团队使用同一种语言(中文或英文),避免混合导致日志风格不一致。
- 结尾不加句号或其他标点
- 推荐长度 50 字符以内,最多不超过 72 字符
好的 subject:修复1分钱购买套餐的bug 差的 subject:修改代码、更新一下、fix bug
body 详细描述
- 用于说明代码变动的动机、实现逻辑、与以前行为的对比
- 可以分成多行,用空行分隔段落
- 可使用自然语言描述,不强制祈使句
- 建议包含:为什么这个变更是必须的?它如何解决问题?是否存在副作用?
footer 脚注
BREAKING CHANGE 不兼容变更
如果当前代码与上一个版本不兼容,Footer 部分以 BREAKING CHANGE: 开头,后面是对变动的描述、变动理由和迁移方法。也可以在 type/scope 后添加 ! 来标识(如 feat!: 删除已废弃接口)。
BREAKING CHANGE: isolate scope bindings definition has changed.
To migrate, follow the example below:
Before: ...
After: ...
关闭 Issue
使用 Closes 关键字关联 Issue(具体关键字取决于代码托管平台,GitHub/GitLab 均支持 Closes、Fixes 等),提交后自动关闭对应 Issue。
Closes #123
Closes #123, #245, #992 # 关闭多个 Issue
跳过 CI
如果希望本次提交不触发 CI 构建,可在 Footer 中添加 [skip ci](也可放在 Subject 或 Body 后单独一行)。
注意:不同 CI 系统可能使用不同关键字,如 GitHub Actions 支持
[skip ci],GitLab CI 支持[ci skip],Travis CI 支持[ci skip]。请根据团队实际使用的 CI 平台确认,或在文档中明确统一使用[skip ci]并确保平台支持。
[skip ci]
特殊类型:Revert
如果当前 commit 用于撤销以前的 commit,必须以 revert: 开头,后面跟着被撤销 Commit 的 Header。
revert: feat(pencil): add 'graphiteWidth' option
This reverts commit 667ecc1654a317a13331b17617d973392f415f02.
示例
基础示例
git commit -m "fix(order): 修复订单金额计算错误"
完整示例
git commit -m "fix(order): 修复1分钱购买套餐的bug
测试反馈可以1分钱买套餐,目前已经卖出了200单
原因是价格校验逻辑未考虑优惠券叠加场景
Closes #2677
[skip ci]
不兼容变更示例
git commit -m "refactor(api): 重构用户信息接口
将 /api/v1/user 接口改为 /api/v2/user,参数结构调整为 JSON 格式
BREAKING CHANGE: 接口路径和参数格式不兼容旧版本,需前端同步更新
Closes #789
相关工具
IDEA 插件:Git Commit Message Helper
在 IDEA 插件市场搜索安装 Git Commit Message Helper,重启后即可在提交时获得交互式提示,自动生成符合规范的 commit message。
VSCode 插件:Git-commit-plugin For VSCode
VSCode 用户可安装此插件,通过表单交互填写 type、scope、subject 等,自动生成规范格式。
Commitizen:命令行交互式工具
-
安装(全局)
npm install -g commitizen -
项目内初始化适配器(使用 Conventional Commits 规范)
commitizen init cz-conventional-changelog --save-dev --save-exact -
使用
git cz # 代替 git commit -
自定义适配器
如需定制 type、scope 列表,可使用
cz-customizable,并在项目根目录创建.cz-config.js配置文件。
Commitlint:提交信息格式校验
-
安装
npm install -g @commitlint/cli @commitlint/config-conventional -
配置(项目根目录创建
commitlint.config.js)// commitlint.config.js module.exports = { extends: ['@commitlint/config-conventional'], rules: { 'type-enum': [2, 'always', [ 'feat', 'fix', 'to', 'docs', 'style', 'refactor', 'perf', 'test', 'build', 'ci', 'chore', 'revert', 'merge', 'sync' ]], 'type-empty': [2, 'never'], 'subject-empty': [2, 'never'], 'header-max-length': [2, 'always', 50], // 可根据团队习惯调整为 100 // 可选:限制 scope 只能使用指定的业务模块 // 'scope-enum': [2, 'always', ['user', 'order', 'payment', 'common']] } };
Husky:集成 Git Hooks
每次 git commit 时都会自动校验提交信息,不合规范则拒绝提交。
-
安装 Husky(以 Husky 6+ 为例)
npm install husky --save-dev npx husky install -
在
package.json中添加prepare脚本,确保其他成员 clone 后自动启用 Husky:"scripts": { "prepare": "husky install" } -
添加 commit-msg hook
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit $1'或直接在
package.json中配置(旧版 Husky):"husky": { "hooks": { "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" } }
其他工具
- standard-version / semantic-release:根据规范的提交记录自动生成 CHANGELOG.md 和版本号(遵循语义化版本)。注意:自定义类型(如
to、sync、merge)默认不会出现在 CHANGELOG 中,如需包含需额外配置。 - validate-commit-msg:另一种校验工具。
附录:常用名词简称
- CR:Code Review(代码审查)
- PR:Pull Request(拉取请求)
- MR:Merge Request(合并请求)
- ACK:Acknowledgement(同意/接受)
- WIP:Work In Progress(进行中)
- RFC:Request For Comment(请求讨论)
- CI:Continuous Integration(持续集成)