关于 conventional-commit
conventional-commit 是用于检查 Git 暂存更改并拟定 Conventional Commits 消息的技能。它会参考项目提交惯例,并在创建提交前征求确认。
主要功能
- 01检查暂存文件和缓存差异
- 02判断更改类别与提交类型
- 03遵循主题、正文和页脚规范
- 04查看近期提交惯例
- 05提交前要求确认
适用场景
- 01为暂存的功能或修复拟定消息
- 02识别可能需要拆分的无关更改
- 03为分支内更改创建修正提交
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ rlespinasse/ agent-skills --skill conventional-commit安装后在 Claude Code 中输入/conventional-commit确认已加载。
附带文件evals/evals.json
详细介绍
使用 Conventional Commits 提交暂存文件
你正在帮助用户使用 Conventional Commits 规范和最佳提交消息实践,提交当前已暂存(已索引)的 git 文件。
提交前检查
编写提交消息前,务必:
- 运行
git status,查看哪些文件已暂存 - 运行
git diff --cached,检查实际暂存的更改 - 如果没有暂存内容,请告知用户并停止操作——不要创建空提交
Conventional Commit 格式
<type>[optional scope]: <subject>
[optional body]
[optional footer(s)]
类型
| 类型 | 使用时机 |
|---|---|
feat | 新功能或新能力 |
fix | 修复错误 |
docs | 仅涉及文档的更改 |
style | 格式、空白、分号更改——不改变逻辑 |
refactor | 重构代码,但不改变行为 |
perf | 性能改进 |
test | 添加或更新测试 |
build | 构建系统或外部依赖更改 |
ci | CI/CD 配置更改 |
chore | 维护任务(依赖更新、工具、配置) |
revert | 撤销先前的提交 |
注意:仅涉及注释的更改(添加、更新或删除代码注释)应使用 style 或
chore——绝不要使用 feat 或 fix。提交消息应简洁;不要描述具体注释内容。
范围
- 可选,但如果更改针对特定模块、组件或区域,建议填写
- 使用小写 kebab-case:
feat(auth):、fix(api-client): - 与项目现有的范围约定保持一致
- 检查近期 git 日志(
git log --oneline -50或更多),了解项目中已使用的范围模式 - 同时留意项目是否实际采用 Conventional Commits;如果没有,请调整以符合项目风格
主题行规则
- 使用祈使语气:“add feature”,而不是“added feature”或“adds feature”
- 首字母小写:“add feature”,而不是“Add feature”
- 末尾不要加句号
- 不超过 50 个字符——硬性上限为 72 个字符
- 确保句意完整:“如果应用此提交,它将 <主题>”
正文规则
- 与主题之间空一行
- 每行不超过 72 个字符
- 说明做了什么以及为什么,而不是如何做(diff 会展示如何做)
- 仅当主题本身不足以理解更改时才填写
- 多项相关更改请使用项目符号
页脚规则
- 对于破坏性更改,使用
BREAKING CHANGE: <description>(会触发主版本号升级) - 使用
Refs: #123或Closes #456引用问题 - 使用
Co-authored-by: Name <email>标注共同作者 - 项目要求开发者来源证明(DCO)时,使用
Signed-off-by: Name <email>
决策流程
按照以下流程确定提交消息:
第 1 步:分析暂存的更改
仔细阅读 diff 并确定:
- 哪些文件发生了更改,以及它们的用途
- 这是一个单一的逻辑更改,还是多个互不相关的更改
- 主要意图:新功能、错误修复、重构等
Step 2:检查是否存在多个逻辑变更
如果暂存的变更包含多个互不相关的变更:
- 告知用户:“暂存的变更包含多个互不相关的变更。 考虑将它们拆分为多个提交,以获得更清晰的提交历史。”
- 将变更分类,并建议合理的分组:
- 整理——格式调整、重命名、删除无用代码(不改变行为)
- 基础设施/构建——依赖项、工具、配置
- 功能实现——新功能
- Bug 修复——纠正错误行为
- 文档——仅文档变更
- 将依赖清单文件与其锁文件放在一起(例如,
package.json+package-lock.json、go.mod+go.sum、Cargo.toml+Cargo.lock、pyproject.toml+ 锁文件) - 建议一个能清晰说明变更脉络的提交顺序:
- 首先提交整理/结构性变更(与行为变更分开)
- 先提交文档,再提交相关代码变更
- 先提交基础设施/构建变更,再提交依赖它们的功能
- 最后提交功能或修复
- 让用户决定是继续创建单个提交,还是拆分提交
Step 3:确定类型
- 问自己:“这项变更的主要意图是什么?”
- 如果功能包含测试,类型应为
feat(而非test) - 如果 Bug 修复包含重构,类型应为
fix(而非refactor) - 类型应体现变更的原因,而非涉及的每个文件
- 例外——范围本身决定类型:当所有变更文件都属于具有专属类型的单一领域时,直接使用该类型,不加范围。例如,如果提交只涉及 CI/CD 文件(如
.github/workflows/),应使用ci:,而非fix(ci):或feat(ci):。docs:(仅文档文件)、test:(仅测试文件)和build:(仅构建配置)也同理。这些类型本身已表明范围,再将其作为括号中的范围添加就显得多余。
Step 4:确定范围
- 查看代码库中受影响的部分
- 查看
git log --oneline -50,了解现有的范围命名惯例 - 如果变更涉及多个领域,可以省略范围,或使用主要领域
Step 5:编写主题
- 用简洁的祈使句描述变更
- 聚焦于对用户或开发者的影响
- 不佳:
fix(api): fixed the bug in the login endpoint - 推荐:
fix(api): return 401 on expired token instead of 500
Step 6:编写正文(如有需要)
以下情况应添加正文:
- 主题未能完整说明变更
- 存在重要背景信息(为何采用此方案、考虑过哪些方案)
- 变更会产生副作用或不易察觉的后果
- 需要记录破坏性变更
Step 7:展示并确认
- 向用户展示完整的提交消息
- 等待用户批准后再执行提交
- 如果用户要求修改,按要求调整
执行提交
执行提交时:
- 多行消息使用带 HEREDOC 的
git commit -m - 绝不使用
--no-verify——遵守提交前钩子 - 除非用户明确要求,绝不使用
--amend - 如果提交前钩子执行失败,先调查并修复问题,然后创建新提交
- 提交后运行
git status,确认操作成功
单行提交
git commit -m "feat(auth): add JWT token refresh endpoint"
多行提交
git commit -m "$(cat <<'EOF'
feat(auth): add JWT token refresh endpoint
Implement automatic token refresh when the access token expires.
The refresh endpoint validates the refresh token and issues a new
access token with a 15-minute expiry.
Closes #234
EOF
)"
示例
简单功能
feat: add dark mode toggle to settings page
带背景说明的 Bug 修复
fix(parser): handle empty input without panic
The YAML parser panicked on empty strings because it attempted
to access the first character without a length check. Now returns
an empty document instead.
Closes #89
破坏性变更
feat(api)!: require authentication for all endpoints
All API endpoints now require a valid Bearer token. Previously,
read-only endpoints were publicly accessible.
BREAKING CHANGE: unauthenticated requests to /api/* now return 401.
Clients must include an Authorization header with a valid token.
Refs: #156
文档更新
docs: add API rate limiting guide
重构
refactor(db): extract connection pooling into dedicated module
Move connection pool logic from the monolithic database module into
its own module to improve testability and separation of concerns.
No behavior change.
应避免的反模式
| 反模式 | 为什么不合适 | 更好的替代方案 |
|---|---|---|
fix: fix bug | 没有提供有用信息 | fix(cart): prevent negative quantities |
update code | 不符合约定式提交规范 | refactor(utils): simplify date parsing |
feat: Added new feature and fixes | 使用过去时,含糊不清,范围混杂 | 拆分为多个独立提交 |
WIP | 在提交历史中毫无意义 | 使用描述性消息或 --fixup |
misc changes | 没有提供有效信息 | 描述实际更改内容 |
fix: fix | 冗余且没有意义 | 描述实际修复内容 |
| 主题超过 72 个字符 | 会影响工具处理和可读性 | 保持简洁,详细内容写在正文中 |
Fixup 提交
当用户表示某项更改是 fixup(例如“这是一个 fixup”“fixup 更改”“附加到上一条提交”)时,应创建一条以引入该问题的原始提交为目标的 fixup! 提交。
Fixup 流程
-
确定分支边界 — 首先确定哪些提交属于当前分支:
git log --oneline $(git merge-base HEAD origin/main)..HEAD这是安全的变基范围。只有此范围内的提交才能作为 fixup 或自动压缩的目标。
-
确定目标提交 — 在 Git 日志中查找引入待修复代码的提交:
- 使用
git log --oneline $(git merge-base HEAD origin/main)..HEAD -- <changed-files>查找当前分支中修改过相同文件的提交 - 选择主题与待修复更改最匹配的提交
- 重要防护措施:如果目标提交不在分支范围内(也就是说,它位于
main上或分支点之前),不要创建 fixup 提交。而应告知用户,并创建一条类型恰当的普通提交(例如fix、ci)
- 使用
-
创建 fixup 提交 — 使用
git commit --fixup <target-sha>:git commit --fixup abc1234这会创建一条消息为
fixup! <original subject>的提交。 -
询问用户是否要自动压缩提交 — 创建 fixup 提交后,询问:
“Fixup 提交已创建。你要现在将其自动压缩到目标提交中吗 (
git rebase --autosquash)?” -
如果用户同意,运行限定在分支范围内、启用自动压缩的交互式变基:
GIT_SEQUENCE_EDITOR=true git rebase --autosquash $(git merge-base HEAD origin/main)使用
GIT_SEQUENCE_EDITOR=true可自动确认变基编辑器,使其以非交互方式运行。 绝不要变基到合并基点之前 — 这会改写与main共享的提交。 -
如果用户拒绝,保留 fixup 提交原样 — 它会在未来的变基中被压缩。
Fixup 示例
# Original commit:
a1b2c3d feat(auth): add OAuth2 login flow
# Fixup commit (auto-generated message):
fixup! feat(auth): add OAuth2 login flow
重要准则
- 始终先检查差异,再编写提交消息 — 不要猜测
- 绝不要提交机密信息(.env、API 密钥、凭据)— 如果已暂存,请提醒用户
- 遵循项目约定 — 检查近期历史记录,了解相关模式
- 每条提交只包含一项逻辑更改 — 适时建议拆分
- 提交前先征求同意 — 始终先提交消息供用户审批