使用 Git Hook 来检查提交日志
提交日志是一个非常重要的信息,良好的格式的提交日志可以如下诸多作用:
提供更多的历史信息,方便快速浏览,快速定位到提交的性质,是bug修复还是新功能等
可以过滤掉某些commit,以便于快速查找信息
可以直接从commit生成change log,省去大家记录版本变动的工作,但是要求大家规范提交注释
可读性好,清晰,不必深入看代码即可了解当前commit的作用。
为 Code Review 做准备
方便跟踪工程历史
提高项目的整体质量,提高个人工程素质
#日志格式
比如,前端和框架就使用如下格式的 Commit message
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
其中,header 是必需的,body 和 footer 可以省略。 不管是哪一个部分,任何一行都不得超过72个字符(或100个字符)。这是为了避免自动换行影响美观。
Header
Header部分只有一行,包括三个字段:type(必需)、scope(可选)和subject(必需)。
type
用于说明 commit 的类别,只允许使用下面10个标识。
- feat:新功能(feature)
- fix:修补bug
- docs:文档(documentation),例如添加注释
- style: 格式,例如格式化代码
- refactor:重构(即不是新增功能,也不是修改bug的代码变动)
- test:增加测试
- build:变更项目依赖或调整项目结构
- perf: 性能优化
- ci: 更改持续集成配置文件等
- chore:构建过程或辅助工具的变动
如果type为feat和fix,则该 commit 将肯定出现在 Change log 之中。其他情况(docs、chore、style、refactor、test)由你决定。
scope
scope用于说明 commit 影响的范围,一般情况为数据层、控制层、视图层等等,框架内部可以用此字段标示出影响的组件及模块、bugfix的可以补充条线作为后期统计的点,视项目不同而不同。
如果你的修改影响了不止一个scope,你可以使用*代替。
#Git Hook
上面然有了明确的日志格式,但是只局限了文档约定。如果随便输入了点日志就点提交,或者是不小心误敲错了类型,那么都将破坏上诉约定。
如何在提交时就读对日志进行检查,避免人为的出现日志错误呢?
毫无疑问,使用 git hook 即可,与提交相关客户端钩子有:
pre-commit
钩子在键入提交信息前运行。 它用于检查即将提交的快照,例如,检查是否有所遗漏,确保测试运行,以及核查代码。 如果该钩子以非零值退出,Git 将放弃此次提交,不过你可以用 git commit --no-verify
来绕过这个环节。 你可以利用该钩子,来检查代码风格是否一致(运行类似 lint
的程序)、尾随空白字符是否存在(自带的钩子就是这么做的),或新方法的文档是否适当。
prepare-commit-msg
钩子在启动提交信息编辑器之前,默认信息被创建之后运行。 它允许你编辑提交者所看到的默认信息。 该钩子接收一些选项:存有当前提交信息的文件的路径、提交类型和修补提交的提交的 SHA-1 校验。 它对一般的提交来说并没有什么用;然而对那些会自动产生默认信息的提交,如提交信息模板、合并提交、压缩提交和修订提交等非常实用。 你可以结合提交模板来使用它,动态地插入信息。
commit-msg
钩子接收一个参数,此参数即上文提到的,存有当前提交信息的临时文件的路径。 如果该钩子脚本以非零值退出,Git 将放弃提交,因此,可以用来在提交通过前验证项目状态或提交信息。 在本章的最后一节,我们将展示如何使用该钩子来核对提交信息是否遵循指定的模板。
post-commit
钩子在整个提交过程完成后运行。 它不接收任何参数,但你可以很容易地通过运行 git log -1 HEAD
来获得最后一次的提交信息。 该钩子一般用于通知之类的事情。
其他还有一些钩子,暂时与此文无关,不做介绍,可参阅 git hook
因此以检查日志来说,则使用 commit-msg
即可。
Git Hook 其实在每个仓库中都已经为我们写好了示例,在项目目录下的 .git/hooks
目录下即可找到一堆名为 xxx.sample 的文件,下图是一个 commit-msg.sample
的示例,要启用钩子,则只用将此文件的 .sample
后缀去掉即可。
但是,这个钩子文件的内容有点陌生,里面看起来是 bash
的脚本代码,写起来似乎没有那么容易。
#使用前端技术栈来快速启用钩子
写点 bash
有点难,用 bash
来验证上面规范的日志那就更难。 但是借助 npm 的强大生态,我们可以使用 commitlint 和 husky 来实现此需求,基本零代码即可实现。
husky 是一个以简化 Git Hook 使用的库, 使用它可以非常方便的安装钩子, 假设我们需要再代码提交前通过测试,则只需要如下两行代码即可:
npx husky add .husky/pre-commit "npm test"
git add .husky/pre-commit
commitlint 是一个专门用来检查提交日志是否符合规范的库,进行检查也需要一行代码即可:
npx --no -- commitlint --edit $1
借助这两个工具,实现日志检查只需要如下的步骤:
假设当前目录已经是git仓库,且具备 package.json
文件(没有则可以直接 npm init -y
生成一个)。
# 安装 husky
npm install husky --save-dev
# 安装 commitlint
npm install --save-dev @commitlint/config-conventional @commitlint/cli
# 启用 husky
npx husky install
# 新增日志检查钩子
npx husky add .husky/commit-msg \"npx --no -- commitlint --edit '$1'\"
至此大功告成,此时如果提交日志不符合规范,git提交将无法创建。
如果修改要验证的git日志的格式,只用在项目根目录下新建一个 commitlint.config.js
文件即可,如允许 scope 为空:
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'scope-enum': [0, 'never']
}
};
具体完整的配置可参考 文档 https://github.com/conventional-changelog/commitlint/blob/master/docs/reference-rules.md
同时,以上的步骤并不需要每个人都照着命令去敲一次,只需要仓库的维护者操作一次,并在 package.json
中的 scrips
下加入 "postinstall": "npx husky install"
即可。 这样其他人在拉取或者更新仓库后只用重新执行下 npm install
即可。
原理: 安装的依赖和配置都已经保存到仓库了,其他人更新后也会有这些依赖和配置, “postinstall” 的作用是在 npm install 之后自动执行 npx husky install
这样就激活了 husky ,所以只用一个人操作一次即可。
#By The Way
最后不只是检查提交提交日志,如果要在提交前检查是否通过了eslint,则可以如下配置:
npx husky add .husky/pre-commit \"npx eslint ./\"
以上的意思是,新增一个 pre-commit
的钩子,执行内容为 npx eslint ./