Conventional Commits 是什么
Conventional Commits 是一份提交信息格式约定:首行写成 <类型>[可选范围]: 描述,空行之后可以跟正文,末尾可以加页脚。约定本身很短,价值在于让提交信息变成机器可解析的结构化数据,从而自动生成变更日志、推导版本号、关联缺陷编号。
为什么要机器可读
团队常见的痛点是发版时说不清这一版究竟改了什么,只能翻提交记录。结构化之后,feat 表示新增功能、fix 表示缺陷修复,破坏性变更用感叹号或 BREAKING CHANGE 页脚点明,工具就能据此生成发布说明,并决定该升主版本还是次版本。
基本信息
| 适用平台 | 与 Git 客户端和托管平台无关,纯文本约定 |
|---|---|
| 规范版本 | Conventional Commits 1.0.0 |
| 首行结构 | <type>[可选 scope]: <描述> |
| 正文与页脚 | 用空行分隔;页脚可写 BREAKING CHANGE、Refs 等 |
| 硬性要求 | feat 与 fix 两个类型,破坏性变更必须显式标注 |
| 配套关系 | 与 SemVer 语义化版本配合,用来自动推导版本号 |
典型使用场景
- 生成变更日志:按类型分组输出 CHANGELOG
- 推导版本号:feat 升次版本、fix 升修订号、破坏性变更升主版本
- 提交校验:在钩子或 CI 里检查格式是否合规
- 关联缺陷:页脚写 Refs #123 让平台自动建立关联
- 回溯基线:发布时快速筛出这一版包含哪些功能与修复
- 协作对齐:新人按模板填写,减少「改了一下」这类无信息提交
示例提交
示例提交
git commit -m 'feat(login): 支持邮箱验证码登录' # 新增功能
git commit -m 'fix(api): 修复分页参数溢出' # 缺陷修复
git commit -m 'docs: 补充部署说明' # 仅文档变更
git commit -m 'refactor(core): 拆出校验函数' # 重构,行为不变
git commit -m 'feat!: 移除 v1 回调接口' # 感叹号表示破坏性变更
git commit -m 'chore(release): 2.0.0' -m 'BREAKING CHANGE: 回调地址改为 v2'
git log --oneline --grep='^feat' -20 # 筛出新增功能类提交首行类型速记
| 类型 | 语义 | 对版本的影响 |
|---|---|---|
| feat | 新增功能 | 次版本号加一 |
| fix | 缺陷修复 | 修订号加一 |
| docs | 只改文档 | 不改变代码行为 |
| refactor | 重构 | 行为不变,通常不升版本 |
| perf | 性能优化 | 通常不升版本 |
| test | 测试相关 | 不升版本 |
| chore | 杂项与构建 | 不升版本 |
规范只硬性要求 feat、fix 两类前缀与破坏性变更的标注,其余类型由团队或工具约定,选一套写进贡献指南即可。
只约定前缀却不做校验,格式很快就会退化。建议在提交钩子或 CI 里加一条解析检查,让约定真正生效而不是写在文档里。
描述写成中文完全可以,但类型与冒号的格式要与工具保持一致:冒号后留一个空格,缺空格可能导致解析失败。
破坏性变更有两种写法:类型后加感叹号,或在正文前用 BREAKING CHANGE 页脚。后者更适合详细说明影响范围与迁移方式。
落地时怎么起步
从最小可用开始:先只强制 feat、fix 两个类型,加上破坏性变更的标注约定,其它类型允许自由填写;等习惯稳定后再逐步收紧。校验放在提交钩子里比放在 CI 里反馈更快,但本地钩子可以被跳过,关键项目最好两边都配。团队还应在贡献指南里写明 scope 的取值,否则范围字段会各写各的。
变更日志工具会按类型分组,所以类型选择必须保持一致:新功能用 feat、缺陷修复用 fix,别自造 update、modify 这类词,工具无法归类。
规范不限制提交信息的语言,中文或英文都可以,但同一个仓库内最好保持统一,便于按关键词检索与生成发布说明。