关于 conventional-commits
为开发者提供 Conventional Commits v1.0.0 提交信息的编写与检查指南,涵盖结构规范及语义化版本映射,便于整理提交历史并支持变更日志生成。
主要功能
- 01Conventional Commits 信息结构
- 02类型、范围、正文与页脚规则
- 03破坏性变更标记方式
- 04提交类型与版本映射
- 05校验及 commitlint 指南
适用场景
- 01编写规范的 Git 提交信息
- 02检查提交信息是否符合规范
- 03配置 commitlint 校验
- 04规划变更日志与版本自动化
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jamie-bitflight/ claude_skills --skill conventional-commits安装后在 Claude Code 中输入/conventional-commits确认已加载。
详细介绍
Conventional Commits
按照 Conventional Commits v1.0.0 规范编写提交消息,以生成结构化的提交历史记录、自动生成变更日志并实现语义化版本控制。
何时使用此技能
在以下情况下使用此技能:
- 为结构化项目编写 git 提交消息
- 根据 Conventional Commits 规范验证提交消息格式
- 使用 commitlint 设置提交消息验证
- 根据提交历史配置变更日志生成
- 实现语义化版本控制自动化
- 检查提交消息是否符合规范
- 培训团队掌握提交消息标准
- 与 semantic-release、commitizen 或 git-cliff 等工具集成
消息结构
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
组成部分
| 组成部分 | 必需 | 描述 | 示例 |
|---|---|---|---|
| type | 是 | 提交类别 | feat、fix、docs |
| scope | 否 | 受影响的代码库部分 | (auth)、(parser) |
| description | 是 | 变更的简短摘要 | add user authentication |
| body | 否 | 详细说明 | 包含背景信息的多个段落 |
| footer | 否 | 破坏性变更、问题引用 | BREAKING CHANGE:、Refs: #123 |
提交类型
必需类型(SemVer 影响)
这些类型是 Conventional Commits 规范要求的,并会直接影响语义化版本控制:
flowchart LR
Fix[fix: Bug fix<br/>for users] --> PatchVer[PATCH<br/>0.0.X]
Feat[feat: New feature<br/>for users] --> MinorVer[MINOR<br/>0.X.0]
Breaking[Any type with<br/>BREAKING CHANGE or !] --> MajorVer[MAJOR<br/>X.0.0]
style PatchVer fill:#e1f5ff
style MinorVer fill:#fff4e1
style MajorVer fill:#ffe1e1
| 类型 | 描述 | SemVer | 示例 |
|---|---|---|---|
feat | 面向用户的新功能 | MINOR (0.X.0) | feat: add user authentication |
fix | 面向用户的错误修复 | PATCH (0.0.X) | fix: prevent crash on empty input |
推荐类型(Angular 约定)
这些类型来自 @commitlint/config-conventional,依据的是 Angular 提交指南。除非包含 BREAKING CHANGE,否则不会隐式影响 SemVer。
| 类型 | 描述 | 示例 |
|---|---|---|
build | 构建系统或外部依赖项变更 | build: update webpack to v5 |
ci | CI 配置变更 | ci: add Node 18 to test matrix |
docs | 仅涉及文档的变更 | docs: update API reference |
perf | 性能改进 | perf: reduce bundle size by 20% |
refactor | 不修复错误或添加功能的代码变更 | refactor: extract validation logic |
style | 代码样式变更(空白、格式) | style: fix indentation |
test | 添加或修正测试 | test: add unit tests for parser |
其他常见类型
| 类型 | 描述 | 示例 |
|---|---|---|
chore | 不修改 src 或 test 文件的变更 | chore: update .gitignore |
revert | 撤销先前的提交 | revert: feat: add user auth |
注意:团队可以在 feat 和 fix 之外定义自定义类型,但 Angular 约定类型已得到广泛的工具支持。
规范规则
以下规则依据 RFC 2119 构成 Conventional Commits 1.0.0 官方规范。
类型和范围
-
提交 必须 以类型作为前缀,该类型由一个名词组成(
feat、fix等),后跟 可选的 范围、可选的!,以及 必需的 末尾冒号和空格。 -
当提交添加新功能时,必须 使用类型
feat。 -
当提交表示修复错误时,必须 使用类型
fix。 -
类型后 可以 提供范围。范围 必须 是描述代码库某个部分的名词,并用括号括起来,例如
fix(parser): -
描述 必须 紧跟在类型/范围前缀后的冒号和空格之后。描述是对代码更改的简短概述,例如
fix: array parsing issue when multiple spaces were contained in string
正文
-
简短描述后 可以 添加较长的提交正文,提供更多上下文信息。正文 必须 在描述后空一行。
-
提交正文格式不限,可以 包含任意数量的段落,各段落之间以换行分隔。
页脚
-
正文后 可以 空一行添加一个或多个页脚。每个页脚 必须 由一个单词标记、一个
:<space>或<space>#分隔符,以及一个字符串值组成(灵感来自 git trailer convention)。 -
页脚的标记 必须 使用
-代替空白字符,例如Acked-by(这有助于将页脚部分与多段正文区分开)。例外情况:可以 使用BREAKING CHANGE作为标记。 -
页脚的值 可以 包含空格和换行。当检测到下一个有效的页脚标记/分隔符组合时,解析 必须 终止。
破坏性变更
-
破坏性变更 必须 在提交的类型/范围前缀中标明,或作为页脚条目注明。
-
如果将破坏性变更作为页脚包含,必须 使用大写文本
BREAKING CHANGE,后跟冒号、空格和描述,例如BREAKING CHANGE: environment variables now take precedence over config files -
如果在类型/范围前缀中包含破坏性变更,必须 在
:前紧接!标明。使用!时,页脚中 可以 省略BREAKING CHANGE:,并 应 使用提交描述说明破坏性变更。
其他规则
-
提交消息中 可以 使用
feat和fix以外的类型,例如docs: update ref docs -
实现者 不得 将构成 Conventional Commits 的信息单元视为区分大小写,但
BREAKING CHANGE除外,它 必须 使用大写。 -
在页脚中用作标记时,
BREAKING-CHANGE必须 与BREAKING CHANGE含义相同。
描述最佳实践
基于 Angular 提交消息指南:
摘要/描述指南
- 使用祈使语气和现在时:“change”,而不是“changed”或“changes”
- 首字母不要大写
- 末尾不要加句点(.)
- 将整个标题(类型 + 范围 + 描述)控制在 72 个字符以内
良好示例
feat: add validation for email input
fix: handle null pointer in user service
docs: update installation instructions
refactor: simplify authentication flow
不良示例(避免使用)
feat: Added validation for email input # Past tense
fix: Handles null pointer in user service # Third person
docs: Update installation instructions. # Period at end, capitalized
FEAT: add validation # Uppercase type (inconsistent)
正文指南
- 使用祈使语气和现在时(与摘要相同)
- 说明更改的动机
- 适当时比较更改前后的行为
- 正文 必须 在描述后空一行
- 建议正文至少包含 20 个字符
破坏性变更
标明破坏性变更的方法
以下三种方式等效:
-
页脚表示法:
feat: allow provided config object to extend other configs BREAKING CHANGE: `extends` key in config file is now used for extending other config files -
类型后缀
!:feat!: remove support for Node 6 -
类型+范围后缀
!:feat(api)!: send an email to the customer when a product is shipped
规则
BREAKING CHANGE必须 使用大写- 用作页脚标记时,
BREAKING-CHANGE与其含义相同 - 破坏性变更 必须 对应 SemVer 中的 MAJOR 版本升级
语义化版本对应关系
flowchart TD
Start([Analyze Commits]) --> CheckBreaking{Any commit has<br/>BREAKING CHANGE<br/>or !?}
CheckBreaking -->|Yes| Major[MAJOR bump<br/>X.0.0]
CheckBreaking -->|No| CheckFeat{Any commit<br/>is feat?}
CheckFeat -->|Yes| Minor[MINOR bump<br/>0.X.0]
CheckFeat -->|No| CheckFix{Any commit<br/>is fix?}
CheckFix -->|Yes| Patch[PATCH bump<br/>0.0.X]
CheckFix -->|No| NoChange[No version change]
Major --> End([Release])
Minor --> End
Patch --> End
NoChange --> End
提交类型与版本映射
| 提交类型 | 版本升级 |
|---|---|
fix | PATCH (0.0.X) |
feat | MINOR (0.X.0) |
BREAKING CHANGE 或 ! | MAJOR (X.0.0) |
原因:根据提交历史实现自动语义化版本控制。
验证模式
标题验证正则表达式
^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?!?:\s.+$
Python 验证示例
import re
CONVENTIONAL_COMMIT_PATTERN = re.compile(
r"^(?P<type>feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)"
r"(?:\((?P<scope>[^)]+)\))?"
r"(?P<breaking>!)?"
r":\s"
r"(?P<description>.+)$"
)
def validate_header(header: str) -> bool:
"""Validate commit header follows Conventional Commits."""
return bool(CONVENTIONAL_COMMIT_PATTERN.match(header))
def parse_header(header: str) -> dict | None:
"""Parse commit header into components."""
match = CONVENTIONAL_COMMIT_PATTERN.match(header)
if not match:
return None
return {
"type": match.group("type"),
"scope": match.group("scope"),
"breaking": bool(match.group("breaking")),
"description": match.group("description"),
}
完整示例
简单提交
feat: add user authentication
fix: prevent crash on empty input
docs: correct spelling of CHANGELOG
带作用域的提交
feat(lang): add Polish language
feat(parser): add ability to parse arrays
fix(auth): handle token expiration correctly
破坏性变更
feat: allow provided config object to extend other configs
BREAKING CHANGE: `extends` key in config file is now used for extending other config files
feat!: send an email to the customer when a product is shipped
feat(api)!: send an email to the customer when a product is shipped
chore!: drop support for Node 6
BREAKING CHANGE: use JavaScript features not available in Node 6.
带页脚的多段正文
fix: prevent racing of requests
Introduce a request id and a reference to latest request. Dismiss
incoming responses other than from latest request.
Remove timeouts which were used to mitigate the racing issue but are
obsolete now.
Reviewed-by: Z
Refs: #123
撤销提交
revert: let us never again speak of the noodle incident
Refs: 676104e, a215868
性能改进
perf: reduce memory allocation in parser by 40%
Replace string concatenation with StringBuilder pattern.
Benchmark results show 40% reduction in heap allocations.
Refs: #456
重构
refactor: extract authentication logic into separate module
Move auth-related functions from utils.py to auth.py.
No functional changes.
构建/CI 变更
ci: add Node 18 to test matrix
build: upgrade webpack from v4 to v5
- Update webpack.config.js for v5 compatibility
- Replace deprecated plugins
- Update all loader dependencies
Refs: #789
测试和样式变更
test: add unit tests for user validation
Cover edge cases for email validation and password strength.
style: format code according to prettier config
chore: update .gitignore to exclude IDE files
与验证工具集成
commitlint 配置
使用 Angular 配置,通过 commitlint 验证提交:
# Install commitlint
npm install --save-dev @commitlint/cli @commitlint/config-conventional
# Create configuration
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
# Test commit message
echo 'feat(api): add new endpoint' | npx commitlint
如需全面了解 commitlint 配置,请参阅本文档中的指南。如果你的工作区安装了 commitlint 插件,可以参考该插件获取项目特定的规则和示例。
提交前钩子
使用提交前钩子强制执行提交消息格式。如果你的工作区安装了提交前插件,可以参考它了解钩子设置方法;否则,请直接配置钩子。
生成变更日志
使用 semantic-release 从 Conventional Commits 生成变更日志:
// release.config.js
module.exports = {
branches: ['main'],
plugins: [
'@semantic-release/commit-analyzer',
'@semantic-release/release-notes-generator',
],
};
也可以使用 git-cliff:
# cliff.toml
[git]
conventional_commits = true
优势
摘自官方规范:
- 自动生成 CHANGELOG - 工具会解析提交历史并生成发布说明
- 自动确定语义化版本升级 - 根据已合并的提交类型确定
- 传达变更性质 - 向队友、公众和利益相关方说明
- 触发构建和发布流程 - CI/CD 流水线会根据特定提交类型作出响应
- 让贡献变得更容易 - 通过结构化的提交历史进行探索
常见问题
可以使用自定义类型吗?
可以。规范没有强制要求使用 feat 和 fix 以外的类型,但除非包含 BREAKING CHANGE,否则这些类型不会隐式影响 SemVer。团队通常会添加 wip、deps、security 等类型。
规范区分大小写吗?
由具体实现决定。大多数工具会将文本规范化为小写。例外:BREAKING CHANGE 必须使用大写。最佳实践:在项目中保持一致。
合并提交该如何处理?
变更日志生成工具通常会忽略合并提交。它们无需遵循此格式。
如果使用了错误的类型,该怎么办?
合并/发布前:使用 git rebase -i 编辑提交历史 发布后:视工具和流程而定 最坏情况:不符合规范的提交会被基于该规范的工具遗漏
所有贡献者都需要使用 Conventional Commits 吗?
不需要。对于基于压缩提交的工作流,主要维护者可以在合并时整理提交消息。许多团队会配置 Git 系统,自动压缩来自拉取请求的提交,并提供表单以填写规范的提交消息。
如何处理撤销提交?
使用 revert 类型,并在页脚中引用被撤销提交的 SHA:
revert: let us never again speak of the noodle incident
Refs: 676104e, a215868
相关技能
提交消息验证与强制执行:
commitlint- 配置并使用 commitlint 验证提交消息。如果有可用的已安装 commitlint 插件,请使用它了解项目专属规则;否则遵循本文档中的指南。pre-commit- 设置 pre-commit 钩子以自动验证。如果有可用的已安装 pre-commit 插件,请使用它了解钩子设置指南;否则直接配置钩子。
Git 工作流工具:
commit-staged- 可选的差异提交消息生成器。如果已安装,可以使用它;否则根据差异和本参考手动生成 Conventional Commit 标题。
参考资料
官方文档
- Conventional Commits v1.0.0 规范 - 官方规范(访问日期:2025-01-15)
- Conventional Commits GitHub 仓库 - 规范源代码仓库
- RFC 2119 - 规范中使用的关键词
相关标准
- 语义化版本(SemVer) - Conventional Commits 与之相配合的版本管理标准
- Angular 提交消息指南 - 启发了 Conventional Commits 的约定
- Git Trailer 格式 - 启发了页脚格式的约定
工具与配置
- @commitlint/config-conventional - Commitlint 可共享配置
- @commitlint/config-angular - Angular 风格的 commitlint 配置
- semantic-release - 自动化版本管理与变更日志
- git-cliff - 变更日志生成器
- commitizen - 交互式提交消息构建器