关于 conventional-commits
这项独立技能用于按 Conventional Commits v1.0.0 编写 Git 提交信息和 Pull Request 标题,并附带 Node.js 验证器检查标题格式。
主要功能
- 01提交信息与 PR 标题规范
- 02类型、范围及破坏性变更指南
- 03SemVer 版本升级对应规则
- 04可运行的 Node.js 标题验证器
适用场景
- 01规范 Git 提交信息格式
- 02检查 Pull Request 标题
- 03提交前验证标题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ axross/ skills --skill conventional-commits安装后在 Claude Code 中输入/conventional-commits确认已加载。
附带文件scripts/check-commit-message.mjs
详细介绍
Conventional Commits
每当你撰写 Git 提交消息或为拉取请求拟定标题时,都使用此能力。它提供了 Conventional Commits v1.0.0 规范——一种发布工具可以解析、人类也能在 git log --oneline 中快速浏览的标头格式——以及一个可运行的验证器,可在格式错误的标头提交之前将其捕获。以下规范性规则摘自该规范,因此应用它们无需联网获取内容。
此技能是自包含的:它不指定任何特定仓库的文件或布局,所包含的规范无论安装在哪里都相同。如果宿主项目对规则作了更严格的限制——例如限定类型列表、要求必须填写范围,或要求包含其工具会读取的提交尾注——则在相应方面遵循宿主项目的惯例,并保留以下结构。
本文档中的关键词 “MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、“MAY” 和 “OPTIONAL”,应按 RFC 2119 中的定义进行解释。
整体格式
<type>[optional scope][!]: <description>
[optional body]
[optional footer(s)]
指南:
- 每条提交消息都必须以
<type>开头,后接可选的范围、可选的!破坏性变更标记、必需的冒号,以及必需的一个空格,然后是描述。 - 第一行(标头:
type(scope)!: description)必须保持为单行,且末尾不得有句点。 - 如果标头、正文和尾注都存在,它们之间必须各用且仅用一个空行分隔。
拉取请求标题
标头格式并非仅用于提交:拉取请求标题必须遵循与提交标头相同的 <type>[scope][!]: <description> 格式,以便无论采用哪种合并策略,标题都保持一致且易于浏览。这在合并时也很重要:压缩合并通常会将拉取请求标题作为压缩提交的主题(在 GitHub 上,多提交的拉取请求默认如此;启用 “Default to pull request title” 后,所有拉取请求均如此),因此,没有类型前缀的标题会导致默认分支上出现不符合规范的提交。标题只包含标头;正文和尾注应放在拉取请求描述中——撰写正文时,请参阅项目关于拉取请求描述的惯例。
指南:
- 每个拉取请求的标题都必须采用 Conventional Commits 标头(
<type>[scope][!]: <description>),并严格遵循下文针对提交标头规定的类型、范围、描述和破坏性变更规则。 - 如果拉取请求涉及多种类型的变更,应根据其主要交付内容选择类型(例如,主要涉及 CI 配置、附带少量文档调整的变更应使用
ci)。 - 不得将此规则用于问题标题:问题应以直白的描述性文字陈述问题或预期交付内容,绝不能作为提交主题。
类型
类型前缀是工具用于确定发布版本增量的依据,因此必须准确体现更改的性质。
指南:
- 新增面向用户的功能时,必须使用
feat—— 对应 SemVer MINOR 增量。 - 修复面向用户的错误时,必须使用
fix—— 对应 SemVer PATCH 增量。 - 对于不影响发布版本的更改,可以使用以下其他类型:
build—— 构建系统或外部依赖项(例如依赖清单或构建配置)。chore—— 不适合归入其他类型的日常维护工作(例如技能编辑、配置调整、仓库元数据)。ci—— CI/CD 配置(例如流水线定义或托管/项目设置)。docs—— 仅涉及文档的更改(例如 README、贡献者文档或 Agent 技能文档)。style—— 仅涉及格式/空白字符,不改变行为(通常由格式化工具生成)。refactor—— 既不修复错误,也不添加功能的代码更改。perf—— 性能改进。test—— 添加或修正测试。revert—— 撤销之前的提交;请参阅下方的撤销示例。
- 解析时必须将类型视为不区分大小写,但为与现有 git 日志保持一致,应使用小写。
范围
范围用于让读者无需打开差异内容,就能了解代码库中哪个部分发生了变化——这很有用,但仅当某个部分明显是主要改动范围时才使用。
指南:
- 可以在类型后立即用括号注明范围,例如
fix(parser): ...。 - 范围必须是名词,用于标识代码库中受影响的部分——优先使用与现有目录结构相符的名称,例如
api、auth、config、e2e、skills,或具体的模块/路由名称。 - 如果更改涉及整个项目,且没有单一的主要部分,应省略范围。
描述
描述是在 git log --oneline 中显示的一行文字;使用祈使语气,读起来应像提交所执行的命令。
指南:
- 描述必须紧跟在
:后面,并简短地以祈使语气概括更改(例如“添加波兰语”,而不是“已添加”或“正在添加”)。 - 完整标题(
type(scope)!: description)应控制在约 72 个字符以内,以便git log --oneline保持易读。 - 描述末尾不得加句号。
正文
差异内容已经展示了更改;正文则用于说明代码本身无法表达的原因,让后续读者了解背景。
指南:
- 可以在描述后空一行添加正文,以补充背景、理由或迁移说明;如果“为什么”无法从差异内容中显而易见地看出,就应添加正文。
- 正文可以包含任意数量、以换行分隔的段落。正文内容不受格式限制。
- 为便于在终端中阅读,正文行应在约 72 个字符处换行,但 URL 和代码片段除外。
页脚
页脚用于添加可由工具提取、无需解析正文即可读取的机器可解析尾随信息——例如问题引用、评审致谢和破坏性更改说明。
BREAKING CHANGE是唯一允许包含空格的标记。带连字符的BREAKING-CHANGE与之同义,同样有效。
指南:
- 可以在正文后空一行添加一个或多个页脚(若省略正文,则在描述后空一行添加)。
- 每个页脚必须以一个词标记开头,后接
:(冒号和空格)或#(空格和井号),再接值。标记中不得包含空白字符,必须用-代替空白字符,例如Reviewed-by:、Acked-by:、Co-authored-by:、Refs: #123、Closes: #45。 - 页脚的值可以跨越空格和换行;只有在解析到下一个有效页脚标记时,当前值才结束。
重大变更
重大变更 MUST 至少通过以下两种方式之一标明(也 MAY 同时使用两种方式):
- 在类型/范围前缀后加上
!,例如feat(api)!: drop support for Node 18。使用!时,MAY 省略BREAKING CHANGE:页脚,描述本身即可作为重大变更说明。 BREAKING CHANGE:页脚(必须使用大写),例如:BREAKING CHANGE: `extends` key in config file is now used for extending other config files
指南:
- 无论类型是
feat、fix还是其他类型,重大变更 MUST 对应 SemVer MAJOR 版本升级。 - MUST 将
BREAKING CHANGE写成大写;其他所有 Conventional Commits 标记在解析时均不区分大小写,但 SHOULD 使用小写。
SemVer 对应关系
SemVer 对应关系将每种 Conventional Commit 格式映射到其表示的版本升级。选择提交的标题类型和重大变更标记时,请使用此表。
| 提交格式 | SemVer 升级 |
|---|---|
fix: ... | PATCH |
feat: ... | MINOR |
带有 ! 或 BREAKING CHANGE: 页脚的任何类型 | MAJOR |
不带 ! 的 chore、docs、style、refactor、test、build、ci、perf、revert | 不升级版本 |
指南:
- 除非提交同时标记了重大变更,否则 MUST 将
fix视为 PATCH,将feat视为 MINOR。 - MUST 将任何
!标记或BREAKING CHANGE:页脚视为 MAJOR。 - MUST NOT 暗示非
feat/fix类型会带来版本升级,除非它们带有重大变更标记。
示例
以下示例展示了常见情况中可接受的提交格式,包括范围、正文、页脚、重大变更和还原提交。
简单格式,无范围、无正文:
docs: correct spelling of CHANGELOG
带范围:
feat(lang): add Polish language
通过 ! 标记重大变更:
feat!: send an email to the customer when a product is shipped
通过带范围的 ! 标记重大变更:
feat(api)!: drop support for Node 18
通过页脚标记重大变更(不带 !):
feat: allow provided config object to extend other configs
BREAKING CHANGE: `extends` key in config file is now used for extending other config files
带正文和多个页脚:
fix: prevent racing of requests
Introduce a request id and a reference to latest request. Dismiss
incoming responses other than from the latest request.
Remove timeouts which were used to mitigate the racing issue but are
obsolete now.
Reviewed-by: Z
Refs: #123
还原提交:
revert: feat(lang): add Polish language
Refs: 676104e, a215868
指南:
- SHOULD 参照最接近的可接受示例来编写新的提交消息。
- 当提交包含多行内容时,MUST 保留标题、正文和页脚之间的空行分隔。
工具说明
除非项目安装了会拒绝格式错误消息的提交钩子或 CI 检查,否则不符合规范的提交会悄然进入项目,除非作者先发现问题。为机械化地发现这类问题,此技能附带 scripts/check-commit-message.mjs:一个依赖精简的 Node 验证器(仅使用标准库),用于根据上述规则检查标题并报告所有违规项。它会从文件参数或标准输入读取消息。
示例:
# Paths are relative to this skill's installed directory — from a message
# file, or piped on stdin:
node scripts/check-commit-message.mjs .git/COMMIT_EDITMSG
printf 'feat(lang): add Polish language' | node scripts/check-commit-message.mjs
- 修改提交或重写历史记录时,请重新检查每个改写后的提交是否仍符合规范,尤其要确认重大变更带有
!或页脚。
指南:
- 如果项目没有通过提交钩子或 CI 检查来强制规范提交消息,MUST 自行遵守此格式。
- SHOULD 在提交前对标题(以及遵循相同格式的拉取请求标题)运行
check-commit-message.mjs,而不是仅凭目测检查。 - MUST 将退出码
1视为格式错误的标题并进行修正,将退出码2视为调用错误(未提供消息);退出码0表示标题符合规范。