☰
Conventional Commits 1.0.0 约定式提交规范完全指南:语法、Spec 条款与落地实践
2026/9/25 5:35:06 网站建设 项目流程
  • 文档

【免费下载链接】conventionalcommits.org

The conventional commits specification

项目地址:https://gitcode.com/gh_mirrors/co/conventionalcommits.org
点击查看免费下载

约定式提交(Conventional Commits)是一套建立在 Git 提交信息之上的轻量级规范,用一套简单清晰的规则帮助团队创建结构化的提交历史,并让自动化工具(如 CHANGELOG 生成、语义化版本自动升级、构建与发布触发)可以在此基础上稳定运行。本文以本仓库content/v1.0.0/index.gr.md(希腊语版,与英文 1.0.0 正式版内容完全一致)为骨架,逐条讲解提交信息结构、规范条款、完整示例与高频 FAQ,并结合作品仓库的站点源码说明这份规范在开源项目中如何被组织、维护与多语言分发。

摘要:什么是约定式提交

约定式提交规范是一种基于提交信息的轻量级约定。它提供了一组简单易记的规则,用于创建显式的提交历史(explicit commit history),从而让在其之上编写自动化工具变得更加容易。这一约定与语义化版本(SemVer)相互呼应——通过在提交信息中描述新增特性(features)、缺陷修复(fixes)与破坏性变更(breaking changes),提交历史可以直接映射到版本号的变化。

简言之:约定式提交让“提交信息”成为人机皆可读的版本元数据来源。

提交信息的结构

规范要求提交信息遵循如下结构:

<type>[optional scope]: <description> [optional body] [optional footer(s)]

即:第一行是“类型 + 可选范围 + 冒号 + 描述”的标题行;正文(body)与脚注(footer)均为可选,且各自与上一部分之间用空行分隔。这份结构模板在本仓库中即作为规范正文的一部分被写入 content/v1.0.0/index.gr.md 等各语言版本文档,并被 Hugo 站点按 Markdown 渲染展示。

核心结构元素

提交信息由以下结构化元素组成,其目的是向你的库/项目的使用者传达变更意图:

  1. fix:—— 类型为fix的提交用于修复代码库中的缺陷,在语义化版本中对应PATCH(补丁版本升级)。
  2. feat:—— 类型为feat的提交用于引入新特性,在语义化版本中对应MINOR(次版本升级)。
  3. BREAKING CHANGE:—— 一个带有BREAKING CHANGE:脚注、或在类型/范围后追加!的提交,表示引入了破坏性 API 变更,在语义化版本中对应MAJOR(主版本升级)。需要特别注意的是,破坏性变更可以是任意类型提交的一部分,不一定非得是feat或fix。
  4. 其他类型(types)—— 除fix:与feat:之外允许使用其他类型。例如基于 Angular 约定演进的@commitlint/config-conventional推荐了build:、chore:、ci:、docs:、style:、refactor:、perf:、test:等。补充说明:这些类型并不被约定式提交规范强制要求,除非它们包含 BREAKING CHANGE,否则对语义化版本号没有隐式影响。
  5. 脚注(footers)—— 除BREAKING CHANGE: <description>之外,还可以提供其他脚注,其格式遵循类似 git trailer 格式的约定(如Reviewed-by:、Refs:等)。
  6. 范围(scope)—— 可以为提交类型提供一个 scope,用于提供额外的上下文信息,写在类型后的圆括号内,例如feat(parser): add ability to parse arrays。

完整示例

以下 6 个示例完整覆盖了规范涉及的主要书写形态,均可直接复制使用。

带描述与破坏性变更脚注的提交

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

带 scope 与!的破坏性变更

feat(api)!: send an email to the customer when a product is shipped

同时使用!与 BREAKING CHANGE 脚注

chore!: drop support for Node 6 BREAKING CHANGE: use JavaScript features not available in Node 6.

无正文的提交

docs: correct spelling of CHANGELOG

带 scope 的提交

feat(lang): add Polish language

多段落正文与多个脚注

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

规范条款(Specification)逐条解析

规范正文使用 RFC 2119 中定义的关键词:MUST(必须)、MUST NOT(禁止)、REQUIRED(要求)、SHALL、SHALL NOT、SHOULD(应当)、SHOULD NOT、RECOMMENDED(推荐)、MAY(可以)、OPTIONAL(可选)。以下 16 条是 1.0.0 版的全部条款:

  1. 提交必须以类型前缀开头:类型由一个名词构成(如feat、fix),其后依次是可选的 scope、可选的!,以及必须存在的冒号与空格。
  2. feat必须用于新增特性:当提交为你的应用或库添加新特性时,必须使用类型feat。
  3. fix必须用于缺陷修复:当提交表示修复你的应用缺陷时,必须使用类型fix。
  4. scope 可选用:scope 可以在类型之后提供,必须由描述代码库某一部分的名词构成,并放在圆括号内,例如fix(parser):。
  5. 描述必须紧跟冒号与空格:描述是对代码变更的简短摘要,例如fix: array parsing issue when multiple spaces were contained in string。
  6. 正文可选用:更长的正文可以在简短描述之后提供,用于补充代码变更的上下文信息;正文必须在描述之后空一行开始。
  7. 正文为自由格式:正文可以是任意数量的段落,段落之间用换行分隔。
  8. 脚注可选用:一个或多个脚注可以在正文之后空一行提供。每个脚注必须由关键词 token、分隔符(:<space>或<space>#)以及字符串值组成——这一设计参考了 git trailer 约定。
  9. 脚注 token 中连字符替代空格:脚注的 token 必须使用-代替空白字符,例如Acked-by(这有助于将脚注部分与多段落的正文区分开)。唯一例外是BREAKING CHANGE,它也可以作为 token 使用。
  10. 脚注值可包含空格与换行:脚注的值可以包含空格和换行,解析过程必须在观察到下一个合法的 token/分隔符组合时终止。
  11. 破坏性变更必须被标记:破坏性变更必须在提交的类型/scope 前缀中,或以脚注条目形式标记。
  12. 作为脚注的格式:如果破坏性变更作为脚注,必须由大写文本BREAKING CHANGE、冒号、空格和描述组成,例如BREAKING CHANGE: environment variables now take precedence over config files。
  13. 作为前缀的格式:如果破坏性变更出现在类型/scope 前缀中,必须通过:之前紧邻的!来标记。若使用了!,则脚注中的BREAKING CHANGE:可以省略,此时应使用提交描述来说明该破坏性变更。
  14. 允许其他类型:除feat与fix之外,可以在提交信息中使用其他类型,例如docs: update ref docs。
  15. 大小写约定:构成约定式提交的信息单元,实现方不得将其视为大小写敏感,唯一例外是BREAKING CHANGE必须大写。
  16. BREAKING-CHANGE同义:当BREAKING-CHANGE作为脚注 token 使用时,必须与BREAKING CHANGE同义。

值得注意的是,条款 9、13、15、16 正是 1.0.0 正式版相对早期 beta 版本的核心收敛点:!语法被正式引入、脚注 token 规则被明确、大小写与同义词边界被收紧,使得不同工具实现之间的解析行为趋于一致。

为什么使用约定式提交

规范文档明确列出了五大收益,这也是团队引入该规范最常引用的理由:

  • 自动生成 CHANGELOG:基于结构化的提交类型,工具可以自动汇总每个版本的变更记录。
  • 自动确定语义化版本升级幅度:根据落地的提交类型(fix→ PATCH、feat→ MINOR、BREAKING CHANGE → MAJOR)自动计算下一个版本号。
  • 向团队成员、公众和其他利益相关者沟通变更性质:提交历史本身就是一份可读的变更公告。
  • 触发构建与发布流程:CI/CD 可以根据提交类型决定是否发布、发布何种版本。
  • 让更多人更容易为项目做贡献:结构化的提交历史降低了新人理解项目演进的门槛。

常见问题(FAQ)与最佳实践

初始开发阶段如何写提交信息?

建议从一开始就按“产品已发布”的标准来写提交。通常总会有人(哪怕是你的同行开发者)在使用你的软件,他们需要知道什么被修复了、什么被破坏了。

提交标题中的类型用大写还是小写?

任何一种写法都可以,但最好保持一致。

提交同时符合多个提交类型时怎么办?

尽可能回退并拆分成多个提交。约定式提交的价值之一,正是推动开发者做出更规整的提交与 PR。

这是否会阻碍快速开发与快速迭代?

它阻止的是“无组织地快速推进”,反而帮助你在跨项目、多贡献者的长期场景下保持速度。

是否会限制开发者只会使用给定的类型?

约定式提交鼓励更多特定类型(如修复)的提交;除此之外,其灵活性允许你的团队自行定义类型,并随时间演进调整。

与 SemVer 的关系?

fix类型提交应翻译为PATCH版本;feat类型提交应翻译为MINOR版本;包含BREAKING CHANGE的提交(无论类型)应翻译为MAJOR版本。

如何给自己对规范的扩展定版本?

推荐使用 SemVer 来发布你自己对规范的扩展(官方鼓励做这样的扩展)。

不小心用错了提交类型怎么办?

  • 用的是规范内但不对的类型(如用fix代替feat):在合并或发布之前,推荐使用git rebase -i编辑提交历史;发布之后,清理方式取决于你所用的工具与流程。
  • 用的是规范外的类型(如把feat写成feet):最坏情况下也不是世界末日——不合规的提交只是会被基于规范的工具跳过而已。

所有贡献者都必须使用规范吗?

不必。如果使用基于 squash 的 Git 工作流,主维护者可以在合并时统一清理提交信息,不增加偶然贡献者的负担。常见做法是让 Git 系统自动 squash PR 中的提交,并向主维护者弹出表单输入正确的合并提交信息。

如何处理 revert(还原)提交?

还原代码可能很复杂:你是在还原多个提交吗?如果还原了一个特性,下一个版本应该是 patch 吗?规范没有显式定义 revert 行为,而是把决定权交给工具作者,利用类型与脚注的灵活性来发展自己的还原处理逻辑。规范给出的一条建议是:使用revert类型,并在脚注中引用被还原的提交 SHA:

revert: let us never again speak of the noodle incident Refs: 676104e, a215868

从仓库源码看规范的站点化落地

本仓库(conventionalcommits.org)就是这份规范的官方站点实现,采用 Hugo 静态站点生成器。理解它的组织方式,有助于你以同样的模式在自己的团队内维护一份可版本化、多语言的规范文档:

  • 规范按版本与语言分目录存放:所有版本的规范位于content/目录下,例如 1.0.0 正式版在content/v1.0.0/,每个语言一个文件,命名形如index.gr.md(希腊语)、index.zh-hans.md(简体中文)、index.md(英文默认),并各自维护一个由config.yaml中的语言配置驱动的版本下拉菜单。当前仓库的 config.yaml 即包含希腊语(gr)语言的weight、title、description与站点内锚点导航(#περίληψη摘要、#προδιαγραφή规范、#συνεισφέρετε贡献),并声明 v1.0.0 为当前版本。
  • 渲染链路:站点的 单页模板 将各语言 Markdown 正文({{.Content}})嵌入到带markdown-body样式类的文章容器中,实现“同一份规范、多语言渲染”。
  • 构建流程:Makefile 定义了compile-assets(进入themes/conventional-commits目录执行npm install && npm run build编译 SCSS 与 JS)与compile-site(执行hugo)两个目标;前端资源构建脚本定义在 themes/conventional-commits/package.json 中。
  • 新增翻译的约定:根据 README.md 的说明,新增语言需在content/<version>/下创建index.<lang>.md,并同步在config.yaml中注册该语言——这与本仓库维护 28 种语言版本的实践一致,也侧面印证了规范文档本身的“机器可读、便于自动处理”的设计取向。

从仓库结构看,规范正文始终是唯一事实来源,站点层只负责多语言、多版本的呈现与导航,这种“规范与展示分离”的组织方式,值得希望在团队内部落地约定式提交的工程团队借鉴。

结语

约定式提交 1.0.0 是一份「小而完整」的规范:它只用 16 条条款就定义了提交信息的语法与语义边界,为 CHANGELOG 生成、语义化版本计算、CI 发布触发等自动化能力提供了稳定的输入格式。无论是从content/v1.0.0/index.md(英文原版)、content/v1.0.0/index.gr.md(希腊语版)还是 config.yaml 中登记的任意语言版本入手,你获得的都是同一份权威内容。把它纳入团队提交流程,配合 squash 合并与 commitlint 等工具,即可在几乎没有额外负担的前提下获得清晰、可机器处理的提交历史。

  • 文档

【免费下载链接】conventionalcommits.org

The conventional commits specification

项目地址:https://gitcode.com/gh_mirrors/co/conventionalcommits.org
点击查看免费下载

相关推荐

上一篇:manga-image-translator模型压缩技术:减小体积不降低性能
下一篇:URL解析实战指南:从基础到高级(C语言实现)

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询