conventional-commit-message
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseConventional Commit Message
Conventional Commit提交信息
Use this skill when writing, amending, reviewing, or suggesting commit messages for repositories that use the preset or compatible Conventional Commits release tooling.
conventional-changelog-conventionalcommits当为使用预设或兼容Conventional Commits发布工具的仓库编写、修改、审核或建议提交信息时,使用此技能。
conventional-changelog-conventionalcommitsCommit Shape
提交信息结构
Use the Conventional Commits 1.0.0 message structure:
text
<type>[optional scope][optional !]: <description>
[optional body]
[optional footer(s)]Rules:
- is required and is followed by an optional parenthesized
type, an optionalscope, and!.: - is required immediately after
description. Keep it concise, changelog-ready, and lower-case unless a proper noun or identifier requires casing. Do not end it with a period.: - is optional and should name a section of the codebase.
scope - A longer body is optional, starts one blank line after the description, and is free-form.
- Footers are optional, start one blank line after the body or description, and each use either or
Token: value.Token #value - Footer tokens use hyphens instead of spaces, such as , except for
Reviewed-by.BREAKING CHANGEis synonymous withBREAKING-CHANGE.BREAKING CHANGE - Footer values may contain spaces and newlines. A footer value ends when the next valid footer token and separator is observed.
- Conventional Commit units are not case-sensitive, except , which must be uppercase when used as that footer token.
BREAKING CHANGE - Prefer one commit per coherent change. If one diff contains unrelated release visible changes, recommend splitting it.
- Write the description so it reads well as a bullet in a generated changelog. Avoid vague implementation notes like ,
add some feature, orupdate stuff. Prefer user-facing outcomes such asfix issue,support custom scopes, orpreserve prerelease tags.require Node.js 22 - Wrap code identifiers in the description in backticks — function, option, flag, type, or file names: ,
add `autocase` to match camelCase and kebab-case forms. GitHub renders backticks in commit messages and generated changelogs preserve them, and they mark words likesupport `--no-*` negationorflagas code where plain prose would be ambiguous.rest - Wrap any -prefixed token that is not an intentional GitHub user mention in backticks — scoped package names (
@), decorators (@types/node), JSDoc/annotation tags (@Injectable). GitHub parses a bare@deprecatedin commit messages and changelogs as a user mention, which can link and notify an unrelated GitHub account.@name - Active verb phrases are usually better than passive sentences. Prefer over
support custom scopesunless passive voice is clearly more natural for the project.custom scopes were added
Breaking changes are indicated by immediately before in the header or by a breaking-change footer. Use the footer when the impact is known:
!:text
feat(parser)!: remove legacy token fallback
BREAKING CHANGE: custom token fallbacks are no longer applied during parsing.If is used and no breaking-change footer is provided, the description is used to describe the breaking change.
!采用Conventional Commits 1.0.0的消息结构:
text
<type>[可选 scope][可选 !]: <描述>
[可选正文]
[可选页脚]规则:
- 为必填项,后面可跟可选的括号包裹的
type、可选的scope以及!。: - 需紧跟在
描述之后,为必填项。描述应简洁、适合生成变更日志,且除专有名词或标识符外均使用小写,结尾不要加句号。: - 为可选项,应指代代码库的某个模块。
scope - 较长的正文为可选内容,需在描述后空一行开始,格式自由。
- 页脚为可选内容,需在正文或描述后空一行开始,每条页脚采用或
Token: 值的格式。Token #值 - 页脚标识使用连字符代替空格,例如,但
Reviewed-by除外。BREAKING CHANGE与BREAKING-CHANGE同义。BREAKING CHANGE - 页脚的值可包含空格和换行符,当遇到下一个有效的页脚标识和分隔符时,当前页脚值结束。
- Conventional Commit的单元不区分大小写,但作为页脚标识时必须大写。
BREAKING CHANGE - 建议每个提交对应一个连贯的变更。如果一个差异包含不相关的、会体现在发布中的变更,建议拆分提交。
- 描述的撰写要使其能作为生成的变更日志中的项目符号清晰呈现。避免模糊的实现说明,如、
add some feature或update stuff。优先使用面向用户的成果描述,例如fix issue、support custom scopes或preserve prerelease tags。require Node.js 22 - 描述中的代码标识符(函数、选项、标志、类型或文件名)需用反引号包裹:、
add `autocase` to match camelCase and kebab-case forms。GitHub会在提交信息中渲染反引号,生成的变更日志也会保留它们,这能将support `--no-*` negation或flag等词标记为代码,避免普通文本带来的歧义。rest - 所有非有意提及GitHub用户的前缀标识需用反引号包裹——如作用域包名(
@)、装饰器(@types/node)、JSDoc/注解标签(@Injectable)。GitHub会将提交信息和变更日志中的裸@deprecated解析为用户提及,可能会链接并通知无关的GitHub账户。@name - 主动动词短语通常比被动句更好。优先使用而非
support custom scopes,除非被动语态在项目中更自然。custom scopes were added
破坏性变更可通过标题中前的或破坏性变更页脚来标识。当已知影响时,使用页脚:
:!text
feat(parser)!: remove legacy token fallback
BREAKING CHANGE: custom token fallbacks are no longer applied during parsing.如果使用了但未提供破坏性变更页脚,则描述将用于说明破坏性变更。
!Type Selection
类型选择
Default visible types:
- : user-facing feature; appears under
feat; bumps minor. Use this when a commit adds a new feature.Features - : accepted alias for
feature; preferfeatunless matching existing project style.feat - : bug fix or correctness fix; appears under
fix; bumps patch. Use this when a commit represents a bug fix.Bug Fixes - : performance improvement; appears under
perf; bumps patch.Performance Improvements - : revert commit; appears under
revert; bumps patch.Reverts
Default hidden types:
- : documentation-only change.
docs - : formatting, whitespace, punctuation, or style-only change with no behavior change.
style - : general maintenance that should not be in changelog and should not bump, used only when no more specific hidden type fits.
chore - : code change that intentionally preserves behavior/API.
refactor - : tests only.
test - : build system, packaging, dependency metadata, generated build setup.
build - : CI workflow or automation-only change.
ci
Treat hidden types as no-changelog and no-bump intent. If a code change clearly must not affect released behavior or API, use a hidden type instead of or , even when source files changed.
fixfeatTypes other than and are allowed by the Conventional Commits specification, but the spec gives them no implicit SemVer effect unless they include a breaking-change marker. This repository's preset assigns additional visibility and bump behavior through its configured commit types.
featfixDo not use as a catch-all for every hidden change. Prefer the hidden type that describes the change most precisely: for package manager, build tooling, dependency metadata, generated build setup, and workspace configuration; for CI-only automation; for tests; for documentation; for behavior-preserving code restructuring; and for formatting-only changes.
chorebuildcitestdocsrefactorstyleDo not add , , or to a hidden commit unless the release impact is intentional. Those signals override the hidden/no-bump intent.
!BREAKING CHANGERelease-AsBefore choosing a hidden type, first ask whether the diff changes the public contract of any published package, even if the changed files are metadata, configuration, tests, generated files, or CI. Public contract includes supported runtime and platform versions, package exports, CLI behavior, config presets, peer dependency requirements, generated output, documented APIs, and default behavior. If the public contract becomes stricter, removes previously supported usage, or changes user-visible behavior, use a visible type. If previously supported usage no longer works, use and a footer.
!BREAKING CHANGECommon red flags for release-visible or breaking impact:
- Raising minimum runtime, platform, browser, or engine support.
- Removing, renaming, or narrowing package exports, entry points, CLI flags, options, config presets, or documented APIs.
- Tightening peer dependency ranges or required external tools.
- Changing generated output, defaults, validation rules, parsing behavior, or lint/config rules that consumers receive.
默认可见类型:
- : 用户可见的功能;会出现在
feat下;升级次版本号。当提交添加新功能时使用此类型。Features - :
feature的可接受别名;除非匹配现有项目风格,否则优先使用feat。feat - : 修复bug或正确性问题;会出现在
fix下;升级修订版本号。当提交代表bug修复时使用此类型。Bug Fixes - : 性能优化;会出现在
perf下;升级修订版本号。Performance Improvements - : 回滚提交;会出现在
revert下;升级修订版本号。Reverts
默认隐藏类型:
- : 仅文档变更。
docs - : 仅格式、空白字符、标点或风格变更,无行为变化。
style - : 常规维护,不应出现在变更日志中,也不应触发版本升级,仅当没有更具体的隐藏类型适用时使用。
chore - : 不改变行为/API的代码变更。
refactor - : 仅测试相关变更。
test - : 构建系统、打包、依赖元数据、生成的构建配置相关变更。
build - : 仅CI工作流或自动化相关变更。
ci
隐藏类型意味着不生成变更日志且不触发版本升级。如果代码变更明确不会影响已发布的行为或API,即使修改了源文件,也应使用隐藏类型而非或。
fixfeatConventional Commits规范允许和之外的类型,但规范未赋予它们隐式的SemVer影响,除非包含破坏性变更标记。本仓库的预设通过配置的提交类型赋予了额外的可见性和版本升级行为。
featfix不要将作为所有隐藏变更的万能类型。优先选择最能准确描述变更的隐藏类型:用于包管理器、构建工具、依赖元数据、生成的构建配置和工作区配置;用于仅CI自动化;用于测试;用于文档;用于保持行为不变的代码重构;用于仅格式变更。
chorebuildcitestdocsrefactorstyle除非有意产生发布影响,否则不要在隐藏提交中添加、或。这些信号会覆盖隐藏/不升级版本的意图。
!BREAKING CHANGERelease-As选择隐藏类型前,首先要判断差异是否改变了任何已发布包的公共契约,即使修改的是元数据、配置、测试、生成文件或CI相关文件。公共契约包括支持的运行时和平台版本、包导出、CLI行为、配置预设、对等依赖要求、生成输出、文档化API和默认行为。如果公共契约变得更严格、移除了之前支持的用法或改变了用户可见的行为,使用可见类型。如果之前支持的用法不再可用,使用和页脚。
!BREAKING CHANGE发布可见或破坏性影响的常见警示信号:
- 提高最低运行时、平台、浏览器或引擎版本要求。
- 移除、重命名或缩小包导出、入口点、CLI标志、选项、配置预设或文档化API。
- 收紧对等依赖范围或要求外部工具。
- 改变生成输出、默认值、验证规则、解析行为或消费者收到的lint/配置规则。
Impact Heuristics
影响判断
Choose the type by release impact, not by file path:
- Public behavior added: .
feat - Public behavior corrected: .
fix - Runtime speed/memory improvement without behavior change: .
perf - Runtime dependency updates in :
dependencies. They change the published package dependency graph, can improve correctness/security/runtime behavior, and should trigger a release even when source code is untouched. Usefixonly if the dependency update changes or removes supported public behavior.! - Public contract made stricter or previously supported usage removed: or
feat!with afix!footer. Example: raisingBREAKING CHANGEto Node.js 22 should use a subject likeengines.node.require Node.js 22 - Internal rewrite with preserved behavior: .
refactor - Dependency lockfile/package-manager maintenance, build tooling, generated build setup, or workspace package-manager configuration with no shipped behavior change: , unless local style strongly prefers another hidden type.
build - CI-only workflow edits: .
ci - Tests added or adjusted without product code impact: .
test - Docs/readme/examples prose only: .
docs - General housekeeping that does not fit the more specific hidden types: .
chore
When unsure whether a source-code change is user-visible, inspect tests and public API usage. If the change is defensive cleanup, migration plumbing, renaming private helpers, lint fixes, or type-only restructuring, prefer a hidden type.
根据发布影响选择类型,而非文件路径:
- 添加了公共行为:。
feat - 修正了公共行为:。
fix - 运行速度/内存优化且无行为变化:。
perf - 中的运行时依赖更新:
dependencies。这些变更会改变已发布包的依赖关系图,可提升正确性/安全性/运行时行为,即使未修改源代码也应触发发布。仅当依赖更新改变或移除了支持的公共行为时使用fix。! - 公共契约变得更严格或移除了之前支持的用法:或
feat!并附带fix!页脚。示例:将BREAKING CHANGE提升至Node.js 22应使用类似engines.node的主题。require Node.js 22 - 内部重构且保持行为不变:。
refactor - 依赖锁文件/包管理器维护、构建工具、生成的构建配置或工作区包管理器配置且无发布行为变化:,除非本地风格强烈偏好其他隐藏类型。
build - 仅CI工作流编辑:。
ci - 添加或调整测试且无产品代码影响:。
test - 仅文档/自述文件/示例文本变更:。
docs - 不适合更具体隐藏类型的常规内务处理:。
chore
当不确定源代码变更是否对用户可见时,检查测试和公共API使用情况。如果变更是防御性清理、迁移管道、重命名私有辅助函数、lint修复或仅类型重构,优先使用隐藏类型。
Scope Selection
范围选择
Before choosing a scope, inspect the repository:
bash
git diff --staged --name-only
git diff --name-only
rg --files -g '*commitlint*' -g '.commitlintrc*' -g 'commitlint.config.*'
rg --files -g 'package.json'Use staged changes first. If nothing is staged, use the working tree diff.
If the project uses commitlint, read its config before choosing a message. The config may define allowed types, allowed scopes, required casing, max lengths, and other local formatting rules. Common locations include , , , , , , , , , , , and .
.commitlintrc.commitlintrc.json.commitlintrc.yaml.commitlintrc.yml.commitlintrc.js.commitlintrc.cjs.commitlintrc.mjs.commitlintrc.tscommitlint.config.jscommitlint.config.cjscommitlint.config.mjscommitlint.config.tsSingle-repo projects:
- Usually omit the scope.
- Use a scope only when the project already has clear scopes such as ,
cli,docs,deps, or subsystem names.release
Monorepos:
- Prefer the affected package name as scope.
- Derive package scopes from workspace package names, existing commitlint , or recent commits.
scope-enum - If commitlint or local tooling supports multiple scopes and one coherent release-visible change affects several published packages, use all affected package scopes instead of collapsing the change to one package.
- Prefer the repository's accepted multiple-scope separator. If local config enables multiple scopes but does not make the separator obvious, validate a comma-separated scope list with commitlint before using it.
- If package names are npm-scoped, follow the repo's existing convention: either the full package name or the unscoped package segment.
- If one package changed, use that package scope.
- If several packages changed for one shared reason, use a shared scope such as ,
deps, ordev-depswhen that scope adds useful meaning.release - For monorepo-wide release-impacting changes that touch many packages, prefer omitting the scope unless the repo requires one. Release tooling usually uses the changed packages, not a scope, to decide which packages are affected.
global - If several packages changed for different reasons, first try to describe the common intent honestly. If the only honest message would be vague or hide release impact, then suggest separate commits.
For dependency-only work:
- Use for runtime dependency updates in
fix(deps)whendependenciesis an accepted scope.deps - Use for development-only tooling dependency updates when that is an accepted scope.
dev-deps
选择范围前,先检查仓库:
bash
git diff --staged --name-only
git diff --name-only
rg --files -g '*commitlint*' -g '.commitlintrc*' -g 'commitlint.config.*'
rg --files -g 'package.json'优先使用暂存的变更。如果没有暂存变更,使用工作区差异。
如果项目使用commitlint,选择消息前先阅读其配置。配置可能定义了允许的类型、允许的范围、必填大小写、最大长度和其他本地格式化规则。常见位置包括、、、、、、、、、、和。
.commitlintrc.commitlintrc.json.commitlintrc.yaml.commitlintrc.yml.commitlintrc.js.commitlintrc.cjs.commitlintrc.mjs.commitlintrc.tscommitlint.config.jscommitlint.config.cjscommitlint.config.mjscommitlint.config.ts单仓库项目:
- 通常省略范围。
- 仅当项目已有明确范围(如、
cli、docs、deps或子系统名称)时使用范围。release
单体仓库(Monorepos):
- 优先使用受影响的包名作为范围。
- 从工作区包名、现有commitlint 或最近的提交中推导包范围。
scope-enum - 如果commitlint或本地工具支持多个范围,且一个连贯的发布可见变更影响多个已发布包,则使用所有受影响的包范围,而非将变更合并到一个包。
- 优先使用仓库接受的多范围分隔符。如果本地配置启用了多范围但未明确分隔符,使用commitlint验证逗号分隔的范围列表后再使用。
- 如果包名是npm作用域的,遵循仓库的现有约定:使用完整包名或非作用域的包段。
- 如果只有一个包变更,使用该包范围。
- 如果多个包因共同原因变更,当、
deps或dev-deps等共享范围能增加有用信息时,使用该共享范围。release - 对于影响多个包的单体仓库级发布变更,除非仓库要求,否则优先省略范围。发布工具通常使用变更的包而非范围来决定受影响的包。
global - 如果多个包因不同原因变更,首先尝试诚实地描述共同意图。如果唯一诚实的消息会模糊或隐藏发布影响,则建议拆分提交。
仅依赖相关工作:
- 当是可接受范围时,使用
deps更新fix(deps)中的运行时依赖。dependencies - 当是可接受范围时,使用它更新仅开发工具的依赖。
dev-deps
Message Construction Workflow
消息构建流程
- Inspect changed files and diff summary.
- Identify the released behavior impact.
- Choose visible vs hidden type.
- Choose the narrowest valid scope.
- Write the subject as a changelog bullet from the user's perspective when visible, or from the maintenance intent when hidden.
- Add body/footer only when needed for breaking changes, issue closure, release-as, or important context.
- If the work is explicitly tied to an issue, PR, bug report, or user-provided tracker URL, include the relevant reference in the commit body/footer. For fixes that should close the issue, use a closing footer such as . For non-closing context, use a non-closing reference such as
Fixes #123..Refs #123. - If commitlint is configured and the CLI is available, validate the candidate before presenting it to the user.
Validate with the local installed commitlint binary first when possible. Prefer over package-manager runners because it avoids package manager environment, sandbox, and registry behavior while still using the repository's installed version and config.
./node_modules/.bin/commitlintbash
echo 'type(scope): subject' | ./node_modules/.bin/commitlintUse package-manager runners only as fallback when the local binary is missing and running them is acceptable in the current environment:
bash
echo 'type(scope): subject' | pnpm commitlint
echo 'type(scope): subject' | npm exec commitlint
echo 'type(scope): subject' | npx commitlintUse the actual candidate message in place of the example. For multi-line messages, use or another command that preserves the full message exactly:
printfbash
printf '%s\n\n%s\n' 'feat(parser)!: remove legacy token fallback' 'BREAKING CHANGE: custom token fallbacks are no longer applied.' | ./node_modules/.bin/commitlintIf commitlint fails, adjust the type, scope, case, or subject length and validate again. If commitlint is configured but the CLI cannot be run in the current environment, tell the user.
Use issue references naturally:
text
fix(parser): handle empty commit body refs #123Use closing keywords only when the commit should close an issue:
text
fix(cli): preserve prerelease tag when appending changelog
Fixes #123.For coherent changes affecting multiple packages in a monorepo, use multiple scopes when supported by the repository:
text
fix(package-a,package-b): preserve compare links
Fixes #123.- 检查变更文件和差异摘要。
- 确定发布行为影响。
- 选择可见或隐藏类型。
- 选择最窄的有效范围。
- 可见类型的主题从用户视角编写为变更日志项目符号,隐藏类型的主题从维护意图编写。
- 仅在需要说明破坏性变更、关闭问题、指定发布版本或提供重要上下文时添加正文/页脚。
- 如果工作明确关联到问题、PR、bug报告或用户提供的跟踪器URL,在提交正文/页脚中包含相关引用。对于应关闭问题的修复,使用类似的关闭页脚。对于非关闭上下文,使用类似
Fixes #123.的非关闭引用。Refs #123. - 如果配置了commitlint且CLI可用,在呈现给用户前验证候选消息。
尽可能优先使用本地安装的commitlint二进制文件。优先使用而非包管理器运行器,因为它避免了包管理器环境、沙箱和注册表行为,同时仍使用仓库的已安装版本和配置。
./node_modules/.bin/commitlintbash
echo 'type(scope): subject' | ./node_modules/.bin/commitlint仅当本地二进制文件缺失且当前环境允许运行时,才使用包管理器运行器作为备选:
bash
echo 'type(scope): subject' | pnpm commitlint
echo 'type(scope): subject' | npm exec commitlint
echo 'type(scope): subject' | npx commitlint用实际候选消息替换示例。对于多行消息,使用或其他能准确保留完整消息的命令:
printfbash
printf '%s\n\n%s\n' 'feat(parser)!: remove legacy token fallback' 'BREAKING CHANGE: custom token fallbacks are no longer applied.' | ./node_modules/.bin/commitlint如果commitlint验证失败,调整类型、范围、大小写或主题长度并重新验证。如果配置了commitlint但当前环境无法运行CLI,告知用户。
自然使用问题引用:
text
fix(parser): handle empty commit body refs #123仅当提交应关闭问题时使用关闭关键字:
text
fix(cli): preserve prerelease tag when appending changelog
Fixes #123.对于单体仓库中影响多个包的连贯变更,当仓库支持时使用多个范围:
text
fix(package-a,package-b): preserve compare links
Fixes #123.Examples
示例
Visible release entries:
text
feat(writer): support scoped package links
feat!: require Node.js 22
feat: add `rest` function to read all remaining arguments
fix(parser): keep issue references from multiline footers
fix(cli): handle `--no-*` flags in strict mode
perf(git-client): avoid duplicate tag lookups
revert: feat(writer): support scoped package linksHidden no-bump entries:
text
refactor(conventional-changelog): simplify context defaults
test(writer): cover empty reference groups
docs(conventionalcommits): clarify hidden commit types
build(dev-deps): update oxlint
ci: use node 22 in tests
chore(release): prepare package metadataMonorepo package scopes:
text
fix(conventional-changelog-writer): preserve reference order
refactor(conventional-commits-parser): split token normalization
test(git-client): cover lightweight tags可见发布条目:
text
feat(writer): support scoped package links
feat!: require Node.js 22
feat: add `rest` function to read all remaining arguments
fix(parser): keep issue references from multiline footers
fix(cli): handle `--no-*` flags in strict mode
perf(git-client): avoid duplicate tag lookups
revert: feat(writer): support scoped package links隐藏无升级条目:
text
refactor(conventional-changelog): simplify context defaults
test(writer): cover empty reference groups
docs(conventionalcommits): clarify hidden commit types
build(dev-deps): update oxlint
ci: use node 22 in tests
chore(release): prepare package metadata单体仓库包范围:
text
fix(conventional-changelog-writer): preserve reference order
refactor(conventional-commits-parser): split token normalization
test(git-client): cover lightweight tagsOutput Style
输出风格
When the user asks for a commit message, output only the recommended message unless they ask for explanation or alternatives. For uncertain impact, provide two concise options and explain the release consequence:
text
fix(parser): handle empty commit bodyor, if no release bump is intended:
text
refactor(parser): handle empty commit body defensively当用户请求提交信息时,仅输出推荐的消息,除非用户要求解释或备选方案。对于不确定的影响,提供两个简洁选项并说明发布后果:
text
fix(parser): handle empty commit body或者,如果无意触发版本升级:
text
refactor(parser): handle empty commit body defensively