什么是git hook和husky
husky 是能够监听 git hooks 的nodejs包,让nodejs开发者处理 git hook 任务变得更加容易。
git hooks 是定制化的脚本程序,实现的功能与相应的git动作相关。那么 git 能够支持的钩子有哪些呢?
| git hooks | 调用时机 | 说明 | |
|---|---|---|---|
| pre-applypatch | git am 执行前 | ||
| applypatch-msg | git am 执行后 | ||
| post-applypatch | git am 执行后 | 不影响git am结果 | |
| pre-commit | git commit 执行前 | 可以用git commit --no-verify绕过 | |
| commit-msg | git commit 执行前 | 可以用 git commit --no-verify绕过 | |
| post-commit | git commit执行后 | 不影响git commit的结果 | |
| pre-merge-commit | git merge执行前 | 可以用git merge --no-verify绕过。 | |
| prepare-commit-msg | git commit执行后,编辑器打开之前 | ||
| pre-rebase | git rebase执行前 | ||
| post-checkout | git checkout或git switch执行后 | 如果不使用--no-checkout参数,则在git clone之后也会执行。 | |
| post-merge | git commit执行后 | 在执行git pull时也会被调用 | |
| pre-push | git push执行前 | ||
| pre-receive | git-receive-pack执行前 | ||
| update | |||
| post-receive | git-receive-pack执行后 | 不影响git-receive-pack的结果 | |
| post-update | 当 git-receive-pack对 git push 作出反应并更新仓库中的引用时 | ||
| push-to-checkout | 当git-receive-pack 对git push做出反应并更新仓库中的引用时,以及当推送试图更新当前被签出的分支且receive.denyCurrentBranch配置被设置为updateInstead时 | ||
| pre-auto-gc | git gc --auto执行前 | ||
| post-rewrite | 执行git commit --amend或git rebase时 | ||
| sendemail-validate | git send-email执行前 | ||
| fsmonitor-watchman | 配置core.fsmonitor被设置为.git/hooks/fsmonitor-watchman或.git/hooks/fsmonitor-watchmanv2时 | ||
| p4-pre-submit | git-p4 submit执行前 | 可以用git-p4 submit --no-verify绕过 | |
| p4-prepare-changelist | git-p4 submit执行后,编辑器启动前 | 可以用git-p4 submit --no-verify绕过 | |
| p4-changelist | git-p4 submit执行并编辑完changelist message后 | 可以用git-p4 submit --no-verify绕过 | |
| p4-post-changelist | git-p4 submit执行后 | ||
| post-index-change | 索引被写入到read-cache.c do_write_locked_index后 |
具体的钩子说明,可以在 git官网 中查看
安装依赖
// 安装commitlint
npm install --save-dev @commitlint/config-conventional @commitlint/cli
// 安装husky
npm install --save-dev husky
commitlint工作原理
commitlint 是一个工具,用来检测 git 提交信息是否遵循定义的规范。通常与 husky 或者 simple-git-hooks 结合使用,在提交时触发。
新建文件
新建commitlint.config.js文件,内容可以为
/**
* feat:新功能
* update:更新某功能
* fix:修补某功能的bug
* refactor:重构某个功能
* optimize: 优化构建工具或运行时性能
* style:仅样式改动
* docs:仅文档新增/改动
* test: 增加测试
* chore:构建过程或辅助工具的变动
*/
module.exports = {
extends: [
'@commitlint/config-conventional'
],
rules: {
'type-enum': [2, 'always', [
'feat', 'update', 'fix', 'refactor', 'optimize', 'style', 'docs', 'test', 'chore'
]],
'type-case': [0],
'type-empty': [0],
'scope-empty': [0],
'scope-case': [0],
'subject-full-stop': [0, 'never'],
'subject-case': [0, 'never'],
'header-max-length': [0, 'always', 72]
}
};
规则由 名称 和 配置数组 组成。配置数组包含
- level(级别),值为
0、1、2、,0为禁用规则,1为将warning,2为error - Applicable(是否应用),值为
always | never, - value(值)
详细的配置规则可以在 commitlint 官网中查看
在package.json文件中添加如下配置
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}
上面的代码就是在 commit-msg 阶段执行 commitlint -E HUSKY_GIT_PARAMS 命令,用来检测执行 git commit 时提交的信息是否满足我们的规范。
测试是否应用成功
// 执行以下命令
git commit -m "first commit"
// 会提示以下错误
husky > commit-msg (node v14.17.3)
⧗ input: first commit
✖ subject may not be empty [subject-empty]
✖ found 1 problems, 0 warnings
// 或者是
⧗ input: feat1: xxx
✖ type must be one of [feat, update, fix, refactor, optimize, style, docs, test, chore] [type-enum]
✖ found 1 problems, 0 warnings
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
我们可以看到commitlint会在git commit执行之前去检测提交信息中是否有我们定义的类型,如果不符合提交规则就拦截提交。
一些重要的坑
husky版本
在windows环境下使用最新的husky会导致没有覆盖./git/hooks下面的钩子
下图是git init初始化之后,./git/hooks中默认的文件
笔者用了3.1.0版本的husky才成功生成了hooks文件
cnpm和npm的问题
使用cnpm和npm下载的依赖可能会导致在husky在执行commit-msg钩子函数时报错。
建议使用 yarn install去下载依赖