Git hook 是 Husky 的绝佳替代品
背景故事
前段时间,我被要求引入一种自动化功能,用于检查提交的文件是否符合负责统一代码格式和代码质量的 linter 规则(例如:,,eslint
等)prettier
stylelint
经过一番研究,我发现最常用的方法是使用husky
with lint-staged
。我安装并配置了这些工具。一切正常。如果文件包含任何无法被 linter 自动修复的错误,提交过程就会被中断,并在终端中显示错误消息。可惜的是,这个解决方案有一个问题。运行husky
和lint-staged
花费的时间比我预期的要多得多。有时甚至比提交过程本身(包括检查文件是否有错误)花费的时间还要长。
Git钩子
由于完成这项任务后还有一些时间,我决定寻找其他解决方案。我又搜索了一下,找到了git-hooks
。我又查阅了一些资料,git-hooks
发现有一个git
解决方案提供了原生解决方案,可以在执行的某些阶段执行一些自定义操作,git
例如提交更改。pre-commit
它引起了我的注意,其简要描述如下:
此钩子由git-commit[1]调用,可以通过
--no-verify
选项绕过。它不接受任何参数,在获取建议的提交日志消息并进行提交之前调用。...”
从上面的文字可以看出,在提交之前,我们有时间执行一些自定义操作,例如 lint 和自动修复暂存文件。所有在此阶段更改的文件都可以添加并包含在同一个提交中(这意味着我们不必创建单独的提交来应用 lint 自动修复的更改)。在阅读了一些关于shell
脚本的知识后,我准备创建我的第一个脚本。git-hook
预先提交
#!/bin/sh
RED="\033[1;31m"
GREEN="\033[1;32m"
NC="\033[0m"
linter_exit_code=1
all_ts_files=$(git diff --cached --diff-filter=d --name-only | grep .ts$)
all_scss_files=$(git diff --cached --diff-filter=d --name-only | grep .scss$)
./node_modules/.bin/eslint $all_ts_files --quiet --fix && ./node_modules/.bin/stylelint $all_scss_files --stdin --quiet --fix
linter_exit_code=$?
git add -f $all_ts_files $all_scss_files
if [ $linter_exit_code -ne 0 ]
then
echo "${RED} ❌ Linter errors have occurred ( ͡ಥ ͜ʖ ͡ಥ)${NC}"
exit 1
else
echo "${GREEN} ✔ Eslint and Stylelint did not find any errors [̲̅$̲̅(̲̅ ͡° ͜ʖ ͡°̲̅)̲̅$̲̅]${NC}"
exit 0
fi
上面的代码发生了什么:
git diff --cached --diff-filter=d --name-only | grep .ts$
→ 我们正在收集所有暂存文件,然后过滤掉已删除的文件(如果不这样做,你的 linter 会抛出这些文件的错误,因为这个 linter 无法解析已删除文件的路径),然后我使用它grep
来只获取我感兴趣的文件。就我而言,我正在为stylelint收集.ts
文件,eslint
.scss
linter_exit_code=$?
→ 保存最后执行操作的退出代码0
(以防没有错误或错误可以通过 linter 自动修复或1
错误无法通过 linter 修复)git add -f $all_ts_files $all_scss_files
→ 添加由 linters 自动修复的文件。我们需要使用-f
flag 来强制git add
在$all_ts_files
和$all_scss_files
为空的情况下执行- 在此脚本的末尾,我根据退出代码值显示正确的信息
创建后,git-hook
我们必须记住更新配置或在配置和创建git
之间创建符号链接:git
git-hook
-
git
命令(适用于每个操作系统)git config core.hooksPath ./git-hooks
-
符号链接(Linux)
ln -s -f ../../git-hooks/pre-commit .git/hooks/pre-commit
值得将上述脚本添加到npm postinstall
,因为每个克隆我们的存储库并运行npm install
脚本的开发人员也将配置git-hooks
概括
git-hooks
事实证明,使用husky
和lint-staged
是一个好主意,因为提交时间加快了大约两倍。此外,我还删除了项目中的两个额外依赖项,这非常有用。
尤其是因为。husky
从Husky 5
文档中我们可以发现,只有开源项目Husky 5
才免费
设置七个步骤git-hooks
- 在项目目录中创建
git-hooks
目录 - 转至
.git/hooks
目录 - 从要使用的钩子名称中删除
.sample
- 将此钩子移动到创建的
git-hooks
目录中 - 创造你的
git-hook
身体 - 更新配置或创建到目录的
git
符号链接git-hooks
.git/hooks
- 将适当的脚本添加到
npm postinstall
命令
简单示例
我准备了一个简单的仓库git-hooks-example来证明它们可以在//git-hooks
上运行。我写了如何测试这个钩子。Linux
Windows
Mac
Redme.md
pre-commit