Git hooks及其husky的落地使用

286 阅读2分钟
  • git hooks 相关

    • git hooks 【三个主要阶段,主要是针对不同阶段实施流程规则】

      • pre-commit 【lint-stage,pre-commit】

      • commit-msg 【commitlint】

        • commitlint的规则使用
          • 语法:rulename:【Level,Applicable,Value】
            • Level [0..2]: 0 disables the rule. For 1 it will be considered a warning for 2 an error.
              • 错误水平,0禁用规则,1不满足规则是warning,2不满足规则时报错
            • Applicable always|never: never inverts the rule.
              • 应用规则方式:always常规正向使用,never规则取反之后作为执行规则
            • Value: value to use for this rule.
              • 匹配规则时的取值
            • 这里要注意:
              • 当 0 时,就是禁用了这条规则,后面的配置已无意义
              • 当 2 时,看看现在最新的规则是真么,如果是always就是原来的规则,当never时就是原来的规则取反后的
              • 这里面要有个意思的就是,先执行Applicable拿到最新的规则,再去执行Level,看看是0还是2,当时2的时候,在看看看第三个value值,带到规则里面执行
            • 举例:
              • 'subject-full-stop': [0, 'never'], // 结束符号 .该条规则关闭【就是当前规则为:不是以.结尾,但是0,就是禁掉这条,所以可以是以.或者不以.结尾】
              • 'subject-full-stop': [2, 'always'], // 结束符号 .满足通过,不满足2报错,翻译就是必须以.结尾【就是当前规则为:以.结尾,但是2,当结尾的东西带到规则里,通过就pass,不通过就直接2报错】
              • 'subject-full-stop': [2, 'never'], // 结束符号不是 .满足通过,不满足2报错,翻译就是必须不以.结尾【就是当前规则为:以.结尾取反就是不以.结尾,但是2,当结尾的东西带到规则里,通过就pass,不通过就直接2报错】
      • pre-push 【 提交前处理一些事,pre-push 】

    • husky 是怎么样玩转git hooks的呢?

      • husky本质就是用来添加git hooks,然后在各自的hook阶段做各自对应的事,执行对应的脚本【可以配合对应阶段的工具,比如pre-commit阶段使用lint-stage,commit-msg阶段使用commitlint】
      • husky主要就是两个命令
        • husky install【npx husky install】
          • husky install 命令做了什么
                事实上,husky install 命令是解决 git hooks 问题的关键
            
                第一步: husky install 会在项目根目录下创建 .husky 以及 .husky/_ 文件夹(文件夹也可以自定义),然后在 .husky/_ 文件夹下创建 husky.sh 脚本文件。 这个文件的作用就是保证通过 husky 创建的脚本能够正常运行,它的实际应用的地方后面会讲到。更多关于这个脚本的讨论可以看这里 github issue。
                第二步: husky install 会运行 git config core.hooksPath ${path/to/hooks_dir},这个命令用来指定 git hooks 的路径,此时观察项目下 .git/config 文件, [core] 下面会多出一条配置: hooksPath = xxx。当 git hooks 被某些命令触发时,Git 会运行 core.hooksPath 指定的文件夹下的 git hook。
            
                更多关于 husky 的配置、命令相关文档,看这这里
                值得注意的是 core.hooksPath 是 Git v2.9 推出的新特性,而 Husky 也是在 v6 版本开始使用 core.hooksPath 这个特性。在这之前的版本,Husky 会直接覆盖 .git/hooks 文件夹下所有的 hook,来使通过 Husky 配置的 hooks 生效。另外,在配置了 core.hooksPath 后 Git 会忽略 .git/hooks 文件夹下的 git hooks
            
        • husky add【npx husky add】
          • 用途:添加 git hooks
          • api语法:npx husky add .husky/hookname{hook_name} {command}
            • hook_name: pre-commit | commit-msg | pre-push ....
            • command: 命令脚本
          • husky add 命令做了什么
                当运行如下命令
                    npx husky add .husky/pre-commit npx eslint
              
                .husky 目录下会新增一个 pre-commit 文件,文件内容为
                    #!/usr/bin/env sh
                    . "$(dirname -- "$0")/_/husky.sh" npx eslint
            
                此时已经成功添加了一个 pre-commit git hook,这个脚本会在运行 git commit 命令时执行。
                在脚本的第二行,引用了上面所说的 .husky.sh 文件,也就是说通过 husky 创建的 git hook 在被触发时,都会执行这个脚本。
                梳理一下,husky 是如何解决原生的 git hooks 的问题的,首先前面已经提到了原生 git hooks 主要的问题是 git 无法跟踪 .git/hooks 下的文件,但是这个问题已经被 git core.hooksPath 解决了,那么新的问题就是,开发者仍然需要手动设置 git core.hooksPath。 husky 在 install 命令中帮助我们设置了 git core.hooksPath,然后在 package.json 的 scripts 中添加 "prepare": "husky install",这样每次安装依赖的时候就会执行 husky install,因此就可以保证设置的 git hooks 可以被触发了。
            
          • 举例:
            • 配合commitlint使用npx husky add .husky/commit-msg "npx --no -- commitlint --edit $1
              • 后续配置commitlint.config.js
            • 配合lint-stage使用npx husky add .husky/pre-commit "npx lint-staged"
              • 后续配置package.json中的lint-stage【lint-stage针对不同的文件处理的工具,可以是node脚本】