规范化git-commit信息
文章目录
前言
在 git 的使用中,一种最佳实践是使用格式化的 commit 信息,这样方便自动化工具进行处理,可以快速生成 Release Notes,甚至可以直接对接 CI 工具进行更进一步的规范化发布流程。那么如何规范化 git commit 信息呢?本文将重点讨论这个。
2020-05-21 更新:为了更加轻量化,使用git-cz替换掉原来主要推荐的commitlizen部分,在最后添加了一个小结部分概览,方便快速在本地开发环境速查命令及使用方式。
一个最基本的 git commit 最佳实践
Git-Commit-Best-Practices这个项目总结了一个最基本的 git commit 实践:
- Commit Related Changes
- Commit Often
- Don’t Commit Half-Done Work
- Test Your Code Before You Commit
- Write Good Commit Messages
- Use Branches
- Agree on A Workflow
而针对其中的Formatting Rules部分,我们将详细讲解下 Angular 的 git commit 规范格式。
Angular 项目的 git commit 规范
首先我们先了解一下Angular项目如何规范化自己的 commit 信息的吧。
Angular 项目可以说是业界最广为流传的 git commit 最佳实践的项目。Angular 的贡献要求必须 git commit 符合自己定义的模板。先来看看 Angular 的 commit 记录长什么样子吧: https://github.com/angular/angular/commits/master

这样的话 Angular 项目组可以很方便的生成Release Notes

Angular 的 git commit 实践
完整的 Angular 的 commit 教程参见的 CONTRIBUTING: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-commit-message-guidelines
Angular 定义的 commit 基本格式如下:
|
|
除了第一行的 Header 部分必填外,其余均可选。注意 Header, Body, Footer 中间有空白行分割。

Header 部分只有一行,包括三个字段:type(必需)、scope(可选)和subject(必需)。
type用于说明 commit 的类别,只允许使用下面 7 个标识:
- feat:新功能(feature)
- fix:修补 bug
- docs:文档(documentation)
- style: 格式(不影响代码运行的变动)
- refactor:重构(即不是新增功能,也不是修改 bug 的代码变动)
- test:增加测试
- chore:构建过程或辅助工具的变动
通常feat和fix会被放入 changelog 中,其他(docs、chore、style、refactor、test)通常不会放入 changelog 中。
scope用于说明 commit 影响的范围,可选值。通常是文件、路径、功能等。对于 Angular 项目已经定死了 scope: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#scope
subject是 commit 目的的简短描述,不超过 50 个字符。如用英语表述:
- 以动词开头,使用第一人称现在时,比如change,而不是changed或changes
- 第一个字母小写
- 结尾不加句号(.)
Body部分是对本次 commit 的详细描述,可以分成多行。可选项。范例:
|
|
Footer 部分只用于两种情况:
- Break Changes
- Closes
Break Changes 范例:
|
|
Closes 范例:
|
|
自动化工具处理 git commit
手写上述的 commit 格式很明显并不怎么方便,而且还有出错的可能性(尽管 git 支持template功能,但是实际使用的时候仍然不是特别方便),为什么不交给自动化工具完成呢?
下面就是重点要介绍的规范化 git commit 消息的工具git-cz。
git-cz是一个简化版的commitizen+cz-conventional-changelog组合,提供了开箱即用的功能,默认使用Angular规范,默认模板不填写scope部分内容。
NOTE: Windows 环境下你需要使用cmd或powershell运行交互式终端,在cygwin/mingw32/msys2等模拟 posix 运行环境下无法正常执行交互式终端菜单。
NOTE: git-cz非常轻量,只提供 Angular 规范的支持。如果你想使用其他规范的 commit,请使用commitizen配合对应的Adapter
开始使用
对于 NodeJS 项目,commitizen 可以将自己的一些脚本添加到package.json中,方便npm script生命周期管理。
快速将一个项目初始化为 commitizen 友好的项目(需要确保当前工程中必须存在package.json文件):
|
|
此时git cz或git-cz命令将出现类似于下面的交互式终端:
|
|

按照之前的 Angular commit 规范格式交互式输入信息即可,是不是比手写方便了许多?
以后,只要是需要git commit的地方,通通替换为git cz或git-cz即可这样交互式的输入符合 Angular commit 规范的 git log 了。其余 commit 的参数也兼容,比如-a, –amend等等。
自动检测 commit 是否符合规范
尽管我们可以在 CI 测试阶段检测 commit 是否符合这个规范,但是能在本地就有反馈不是更快吗?因此我们可以考虑在git commit的hook中加入commitlint检测,不符合 commit 规范的提交在本地就无法提交进去。
安装@commitlint/cli和@commitlint/config-conventional这两个包(建议安装到全局,这样所有项目都可以用):
|
|
每次 commit 之后可以使用下述命令检测:
|
|
-e/–edit参数代表读取 git commit 最后一条记录。如果希望检测最近几条 commit 记录,可以用:
|
|
-f/–from参数可以指明从哪一条 commit 记录开始检测,还可以配合-t/–to参数检测一个 commit 区间段。
版本发布
重头戏来了。规范化 commit 记录的作用就是为了方便我们知道每次发布之后到底改了什么内容。利用conventional-changelog这个工具可以很方便的帮我们产生 changelog。
|
|
如果之前每次 commit 都使用规范化的 commit 提交,那么使用:
|
|
应该看到这样的 markdown:
|
|
这就是一个基本的CHANGELOG.md雏形,你可以自己复制到CHANGELOG.md并进行相应的修改。也可以直接输出到CHANGELOG.md文件中:
|
|
终端中看到的内容将输出到CHANGELOG.md文件。再次使用上述命令可以将新的 change log 追加到文件中。可以追加-r 0参数代表将 commit 记录从头至尾全部生成 changelog。
更自动化的发布方式 standard-version
在conventional-changelog的官方文档中,官方更鼓励使用更上层的工具standard-version来产生CHANGELOG.md。conventional-changelog可以帮助我们快速检查要生成的 CHANGELOG.md 的格式是否符合期望,而standard-version可以自动帮助我们做以下几件事情:
- 升级元数据中的版本号(如package.json,composer.json等等)
- 使用conventional-changelog更新 CHANGELOG.md
- 提交package.json (如果有) 和 CHANGELOG.md
- 给新版本打一个 tag
首先安装 standard-version 到全局命令行:
|
|
执行下standard-version,将看到类似于下面这样的输出:
|
|
可以非常清楚的从终端上看到standard-version做了哪些事情。检查 git log 可以看到新增了一条 commit 记录:
|
|
项目中也生成了一个CHANGELOG.md文件:
|
|
standard-version 一些基本用法
直接跟空参运行的行为我们已经看到了,一些基本参数介绍下:
- –dry-run: 强烈建议正式运行之前先加这个参数,打印一下要做的事情,并不真正执行
- –first-release/-f: 首次发布,加上这个参数代表不会升级版本号。仅第一次使用需要
- –commit-all/-a: 等效于git commit -a,建议自己决定要提交哪些文件,都add没问题之后再执行standard-version
- –release-as/-r: 手工指定下一个版本号(格式
<major|minor|patch>)。这个参数可能会经常使用。standard-version默认规则是从major/minor/patch中最后一个非零的字段开始累加,如v1.0.0 -> v2.0.0, v1.1.0 -> v1.2.0, v1.1.1 -> v1.1.2,指定这个参数可以规避这个规则,从自定义的版本号开始重新按上述规则升级 - –prerelease/-p: 预发布版本,默认产生的 tag 像这样: v1.0.1-0。可以跟上一个可选的 tag id。如-p alpha,将产生这样的 tag: v1.0.1-alpha.0
转载
文章作者 Forz
上次更新 2021-01-12