不懂鸟语的人
我的个人学习笔记

git commit 规范约束探索

起因

今天看到同事的 commit message 很随意,我觉得不能再这么下去了。
于是我和朋友讨论了一下这件事和解决方案,感觉靠自觉还不如靠自动化检查。

找了些什么

于是我去网上找了一下这方面的工具,找到了以下的解决方案:

  • commitizen

  • commitlint

前者的方案是另起了一个 git cz 命令来进入commitizen 的使用流程,需要手动选择一个 commit type。

这样的操作略显繁琐,而且因为对原有 git commit 命令没有干扰,所以并不是很严格。而且在其他的 git GUI 工具中这个就不是很容易来利用这个了。

于是,我看了一下后者:commitlint,这个是利用了 husky 这个 git hook 工具,hook 了原有的 git commit 命令,对 commit 操作进行了拦截检查。

显然后者更符合我的需求。

部署

依赖于 node/npm 环境,这个需要事现安装好。

安装依赖

运行以下命令进行安装:

1
npm install --save-dev @commitlint/cli @commitlint/config-conventional husky

这行命令安装了三个包:

  • @commitlint/cli: commitlint 的 CLI 工具

  • @commitlint/config-conventional: commitlint 的 conventional 规范配置方案,这是一个从 config-angular 衍生出的一个分支

  • husky: 一款 git hook 工具,可以 hook git 的命令

    补充:
    --save-dev 参数表示将依赖写进 package.json 的 devDependencies 中,devDependencies 中的依赖只会在开发时安装,在部署时会被忽略。

Commitlint 配置

项目根目录新建文件 commitlint.config.js 来存放 commitlint 的配置信息,写入以下内容:

1
2
3
module.exports = {
extends: ['@commitlint/config-conventional']
}

@commitlint/config-conventional 是刚才安装的 commitlint 规范配置方案,可以安装并替换为其他的配置(例如 config-angular)。

Husky 配置

有两种配置方式

方式一

在根目录的 package.json 加入以下配置信息:

1
2
3
4
5
6
7
{
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}
}

方式二

Husky 的版本 >= 1.0.0

.huskyrc 或 .huskyrc.json 或者 .huskyrc.js 文件建在根目录,写入以下内容:

1
2
3
4
5
{
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}

另外看一下里面具体写了些什么:

commit-msg 代表对 commit message 进行 hook,hook 的时候执行后面的命令 commitlint -E HUSKY_GIT_PARAMS 进行检查。

可以直接在命令行执行 commitlint -h 看一下 commitlint CLI 的具体用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@commitlint/cli@8.2.0 - Lint your commit messages

[input] reads from stdin if --edit, --env, --from and --to are omitted
--color, -c toggle colored output, defaults to: true
--config, -g path to the config file
--cwd, -d directory to execute in, defaults to: D:\Projects\video_studio
--edit, -e read last commit message from the specified file or fallbacks to ./.git/COMMIT_EDITMSG
--env, -E check message in the file at path given by environment variable value
--extends, -x array of shareable configurations to extend
--help, -h display this help message
--from, -f lower end of the commit range to lint; applies if edit=false
--format, -o output format of the results
--parser-preset, -p configuration preset to use for conventional-commits-parser
--quiet, -q toggle console output
--to, -t upper end of the commit range to lint; applies if edit=false
--version, -v display version information
--verbose, -V enable verbose output for reports without problems

这里用到的 commitlint -Ecommitlint --env 的简写。

测试一下

到此,部署完毕,可以试一下效果。

1
2
git add commitlint.config.js
git commit -m "test"

可以看到检查和报错:

1
2
3
4
5
6
7
8
9
husky > commit-msg (node v8.16.0)
⧗ input: test
✖ subject may not be empty [subject-empty]
type may not be empty [type-empty]

✖ found 2 problems, 0 warnings
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint

husky > commit-msg hook failed (add --no-verify to bypass)

完毕~