git hooks介绍
Git钩子
当我们在项目下执行git init
时,我们会发现项目下多了一个.git
文件夹(隐藏文件),记录了git
的相关信息,文件夹下的第一个文件hooks
存储了git
的钩子。类似于vue
和react
的生命周期钩子,它可以让我们在一些特定的时刻执行某些操作。
git
的钩子分为两大类:客户端的和服务的。当我们执行了代码提交合并等操作时可以调用客户端的相关钩子。服务端接收到被推送的提交等操作时可以调用服务端的相关钩子。钩子的具体介绍可参考官网。
hooks
文件夹下有每个钩子的示例脚本,去掉扩展名即可激活该钩子脚本,这样一来,它就能被git
调用。
我们在团队合作的项目中经常需要使用到的钩子如下:
pre-commit
钩子在键入提交信息前运行。它用于检查即将提交的快照,例如我们可以在此钩子中检查我们的代码是否有格式问题、语法问题、进行自动化测试等等。如果该钩子以非零值退出,git
将放弃此次提交。但是我们可以用git commit --no-verify
来绕过这个环节。commit-msg
钩子接收一个参数,存有当前提交信息的临时文件的路径。如果该钩子脚本以非零值退出,git
将放弃提交,因此,可以用来在提交通过前验证项目状态或提交信息。
但是由于.git
文件夹是我们本地的隐藏文件,是无法上传到我们的代码仓库中的。所以在团队协作当中就需要使用工具,来统一配置我们的git hooks
。常使用的工具有husky
,使用方法如下:
npx husky-init && npm install
执行完之后,我们的项目下会新增一个.husky
文件夹,下面会初始化一个pre-commit
脚本。package.json
下的scripts
会新增一条"prepare": "husky install"
,意为在项目安装依赖完成后执行husky install
,该命令会创建.husky/
目录并指定该目录为git hooks
所在的目录。
我们在执行git commit
之后,就会执行pre-commit
这个脚本。将脚本改为:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
eslint --fix ./src --ext .vue,.js,.ts
修改完成后,当我们执行git commit -m "xxx"
时,会先对src
目录下所有的.vue、.js、.ts
文件执行 eslint --fix
命令,如果ESLint
通过,成功commit
,否则终止commit
。
但是这样会存在一个问题,会对我们项目中的所有文件执行eslint
校验,耗时会比较长,我们如果仅仅是想要校验修改过的文件要怎么做呢?这个时候我们需要借助另一个工具lint-staged
,仅仅对暂存区的文件进行校验。
首先需要进行安装:
npm i lint-staged -D
在package.json
里增加lint-staged
配置项:
"lint-staged": {
"*.{vue,js,ts}": "eslint --fix"
}
最后再次修改我们的pre-commit
脚本:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged
再次执行git commit
,就仅仅只会对暂存区的文件进行校验了。
当我们使用@vue/cli
脚手架时,脚手架安装完成后也会安装yorkie
,它也可以让我们在package.json
的 gitHooks
字段中方便地指定git hooks
,yorkie
其实是fork
自husyk
,然后做了一些定制化改动,使用方法如下:
在package.json
中新增:
"gitHooks": {
"pre-commit": "lint-staged"
},
"lint-staged": {
"*.{js,vue}": [
"vue-cli-service lint",
"git add"
]
}
参考文章
1、自定义 Git - Git 钩子
2、husky
3、CLI 服务