Featured image of post 约定式提交 Conventional Commits

约定式提交 Conventional Commits

让commit整洁起来

前段时间在公司提交代码的时候,看到仓库密密麻麻格式不一的commit记录有点头疼🤣,去问了下同事发现这块好像大家普遍都不注重,因此专门做了下关于约定式提交的调查。

为什么要规范commit

代码的Git提交是每个项目必经且十分频繁的操作,一个大型的、长期的项目如果在没有commit规范的情况下进行迭代,在经由不同的时期、不同的团队迭代后,commit记录会出现五花八门的格式,一是每个人的信息格式不一致会导致查阅者获取关键信息的效率低,二是时间久了就会出现因commit消息不清晰导致无法有效追溯变更记录。

这种情况在开源社区更是常见,因此基本上所有大型的开源项目为了保证信息规整有效,都会设立对应项目的commit规范。这不仅对于获取commit有效信息有很大的帮助,同时会让一个开发者去注意思考每次commit的功能、特性划分的合理性,如果配合一定的工具,还能够简便的生成规范的release日志。

其实说白了主要目的就是:

  • 规范代码commit的信息,提高获取关键信息的效率,减少因团队更迭后造成的信息出入
  • 通过git工具,快速生成标准release日志
  • 获得共识,对齐业界(好歹别太low对吧🤪)

业界调研

当前我所在的公司没有commit的明确规范标准,而业界当前大部分的commit规范是基于「Angular Commit Guidelines」,这是一个js的commit规范,但是由于其定义的严谨性和通用性而被大部分项目采纳。

实际上这块还涉及一个版本号管理规范「语义化版本 2.0.0 | Semantic Versioning」,起初也是前端为了管理包版本设计的)

项目 Blocky React 高德地图 Bootstrap nginx electron openwrt
公司(社区) Google Meta 阿里 Twitter nginx electron openwrt/lede
commit规范 约定式提交(基于 Angular Commit Guidelines) Angular Commit Guidelines 如何规范你的Git commit?(基于Angular Commit Guidelines) tbaggery - A Note About Git Commit Messages Contributing Changes (nginx.org) 约定式提交(基于 Angular Commit Guidelines) [OpenWrt Wiki] Submitting patches
共性 1. 以commit类型为开头,例如feat,fix,build
2. 类型后紧跟描述信息
3. subject或description长度不是都限制,但一般不宜超过50~100,力求言简意赅
4. body、footer可选,可以没有
5. 不在末尾增加句号
6. 会根据项目特性进行适当调整

Angular Commit Guidelines文档介绍中提及了「Google Style Guides | styleguide」,其部分设计思路是遵循该文档。

约定式提交使用介绍

特点

约定式提交则在保留了Angular规范的基础上,进行了部分调整和优化,例如明确允许scope的内容可选填(实际上阿里的规范也有这个优化,业内社区也普遍没有要求scope内容);在具有破坏性的commit上使用「!」标记(对标SemVer强调破坏性提交的特点)等,并且谷歌、electorn等公司、项目也有使用,也算是受到业界认可的规范标准。

当然还有最重要的一点是,他有专门的社区维护,文档十分的完善,基本我们可以做到开箱即用,并且社区也提供了一些自动化工具。

具体规范我就不过多介绍(因为官方文档真的很详细了),以下摘抄一部分官方文档,可以感受下。

官方文档

概述

约定式提交规范是一种基于提交信息的轻量级约定。 它提供了一组简单规则来创建清晰的提交历史; 这更有利于编写自动化工具。 通过在提交信息中描述功能、修复和破坏性变更, 使这种惯例与 SemVer 相互对应。

提交说明的结构如下所示:

1
2
3
4
5
<类型>[可选 范围]: <描述>

[可选 正文]

[可选 脚注]

提交说明包含了下面的结构化元素,以向类库使用者表明其意图:

  • fix: 类型 为 fix 的提交表示在代码库中修复了一个 bug(这和语义化版本中的 PATCH 相对应)。
  • feat: 类型 为 feat 的提交表示在代码库中新增了一个功能(这和语义化版本中的 MINOR 相对应)。
  • BREAKING CHANGE: 在脚注中包含 BREAKING CHANGE: 或 <类型>(范围) 后面有一个 ! 的提交,表示引入了破坏性 API 变更(这和语义化版本中的 MAJOR 相对应)。 破坏性变更可以是任意 类型 提交的一部分。
  • 除 fix: 和 feat: 之外,也可以使用其它提交 类型 ,例如 @commitlint/config-conventional(基于 Angular 约定)中推荐的 build:、chore:、 ci:、docs:、style:、refactor:、perf:、test:,等等。
  • 脚注中除了 BREAKING CHANGE: ,其它条目应该采用类似 git trailer format 这样的惯例。

其它提交类型在约定式提交规范中并没有强制限制,并且在语义化版本中没有隐式影响(除非它们包含 BREAKING CHANGE)。 可以为提交类型添加一个围在圆括号内的范围,以为其提供额外的上下文信息。例如 feat(parser): adds ability to parse arrays.

示例

包含了描述并且脚注中有破坏性变更的提交说明

1
2
3
feat: allow provided config object to extend other configs

BREAKING CHANGE: `extends` key in config file is now used for extending other config files

包含了 ! 字符以提醒注意破坏性变更的提交说明

1
feat!: send an email to the customer when a product is shipped

包含了范围和破坏性变更 ! 的提交說明

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

包含了 ! 和 BREAKING CHANGE 脚注的提交说明

1
2
3
chore!: drop support for Node 6

BREAKING CHANGE: use JavaScript features not available in Node 6.

不包含正文的提交说明

1
docs: correct spelling of CHANGELOG

包含范围的提交说明

1
feat(lang): add polish language

包含多行正文和多行脚注的提交说明

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
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

为什么使用约定式提交

  • 自动化生成 CHANGELOG。
  • 基于提交的类型,自动决定语义化的版本变更。
  • 向同事、公众与其他利益关系者传达变化的性质。
  • 触发构建和部署流程。
  • 让人们探索一个更加结构化的提交历史,以便降低对你的项目做出贡献的难度。

根据commit生成release日志

既然commit有了固定的格式,那我们自然可以根据这个格式来生成标准的日志啦
由于公司项目不是前端项目,也不是新项目,实在没法使用社区里自带的日志生成工具,于是就自己写了段shell支持🫠

1
2
3
4
5
git log --pretty=format:"%s https://url/commit/%H" | \
sed '/'$(git show-ref --tags | grep "project/v" | awk 'END{print}' | awk '{print $1}')'/,$d' | \
grep -E "^(feat|fix|refactor|chore): " | \
grep -v Merge | awk -F': ' '{print "["$1"]",$2}' | \
sed 's:\[feat\]:\[feature\]:g' | sed 's:\[fix\]:\[bugfix\]:g'

效果图

已经分享给公司的同事,希望今后团队commit能有改善吧🤣


相关文档:

学习
Licensed under CC BY-NC-SA 4.0