05-git的hooks钩子

462 阅读3分钟

git hooks

hooks钩子,其实就是生命周期的意思,git为每次commit代码、push代码等等操作之前都会执行对应的生命周期钩子 -- git hooks

前面说过,在执行特定操作之前就会执行对应的钩子,而且为了让钩子可以配置,让用户自定义,在项目的.git目录下的hooks目录下,暴露了所以的钩子文件(但是他们都是不可用的,只是示例文件 xxx.sample文件,只有将这么文件的.sample文件后缀去除才可以使用)

pre-commit.sample // 把.sample去掉,当执行commit的时候会执行pre-commit文件的内容
pre-push.sample

hooks示例

步骤:

  1. 进入.git/hooks下,ls -la查询所有文件及其权限,touch pre-commit创建 commit 执行前的钩子文件

  2. vim pre-commit 编辑文件内如:

    echo pre-commit hook 
    

    退出保存,为文件添加可执行权限:chmod +x pre-commit

  3. 回到顶级目录下,添加一些内容进行git add .,git commit -m "init"

最后果然输出了:pre-commit hook

项目目录下的hooks配置

当多人合作开发的时候,大家需要的git hooks需要一致(也要一起上传到远程仓库),并且需要简便的可配置话,我们需要做出如下改变。

在根目录下创建 .git_hooks 文件夹,将git默认的hooks文件设置从 .git/hooks 改为 .git_hooks,因此.git_hooks这个文件夹就可以和.git/hooks一样,编写pre-commit文件作为commit的钩子

git config core.hooksPath .git_hooks

我们可以通过.git/config查看当前的git配置

[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
        precomposeunicode = true
        hooksPath = .git_hooks

hooks内容执行规则

hooks文件是作为终端直接输入执行的,比如:

  • 打印信息:

    // pre-commit 文件内容
    echo '这是git hook执行输出的内容'
    
  • 执行eslint

    // pre-commit 执行eslint
    npx eslint ./src
    

主要注意的是,无论你的hooks文件放在那里,最终执行的时候:所有的相对路径都是相对项目根目录

husky出场

husky官网 非常推荐看看作者关于v4 => v7的两篇文章(husky的原理)

husky在v4之前的实现:

通过配置.huskyrc.js

module.exports = {
  hooks: {
    'pre-commit': 'cmd'
  }
}

然后再.git/hooks添加多有的hook钩子文件,文件里这样进行判断:

pre-commit (native) → husky/runner.js (node)
  → is a pre-commit defined in `.huskyrc.js`? → YES, run it

commit-msg (native) → husky/runner.js (node)
  → is a commit-msg defined in `.huskyrc.js`? → NO, do nothing

你肯定发现问题,为啥需要为所有的hook添加判断,不能需要什么hooks就往.git/hooks添加对应的hooks吗?

还真不行,我们无法确保.git/hooks和.huskyrc.js文件进行同步:如果是这样的话需要根据.huskyrc.js生成对应的.git/hooks(在.huskyrc.js删除,也得在.git/hooks删除,添加和修改都得同步)

v6之后的husky如何工作

  • git 支持 core.hooksPath的配置了
  • npm包的最佳实践,husky不自动的安装了(以前会预安装,但是无法确保能给出安装提示信息)

husky希望将所有的hooks放入目录下的.husky文件下,然后设置 git config core.hooksPath .husky。因此需要生成.husky的命令:

npm i husky -D
npx husky install // 在目录下生成 .husky文件夹
npx set-script prepare "husky install" // 设置 package.json的script的内容

如果你希望全自动的做这些事情可以:

npx husky-init && npm install
// 自动的帮你完成上面的三步操作

添加钩子

npx husky add .husky/pre-commit "npm run eslint"

卸载钩子

npm uninstall husky && git config --unset core.hooksPath

总结

本文所有案例实践都在 code-example / 09-example05-git_hooks