为什么你需要 Git Hooks?
你有没有遇到过这种情况:同事提交了一堆代码,结果因为格式不一致、缺少注释或者没跑测试,导致整个构建挂了。
你花了半小时排查,最后发现只是缩进用了 tab 而不是空格。
这种问题完全可以通过 Git Hooks 提前拦截。Git 内置了一套钩子系统,在代码生命周期中的关键节点自动触发脚本。你不需要装任何第三方工具,Git 本身就能干活。
Git Hooks 的工作原理
Git Hooks 存放在项目根目录的 .git/hooks/ 文件夹里。当你执行某个 Git 操作时,Git 会检查对应的钩子脚本是否存在且可执行,如果存在就运行它。
常见的钩子类型:
- pre-commit:提交前运行,检查即将提交的内容
- commit-msg:提交信息写入前运行,可以校验提交格式
- pre-push:推送到远程前运行,可以阻止不合规范的推送
- post-commit:提交完成后运行,适合发通知或触发 CI
这些脚本可以是 Shell、Python、Node.js 甚至 Go 写的。只要第一行指定了解释器,Git 就会调用它执行。
实战一:安装 Husky 管理 Hooks
手动在 .git/hooks/ 里写脚本太麻烦了,而且换台机器就要重新配。业界最流行的方案是用 Husky。
先安装:
npm install husky --save-dev
npx husky init
这会在项目里创建 .husky/pre-commit 文件,里面默认只有一行 npm test。你可以改成任何你想在提交前运行的命令。
比如运行 ESLint 检查:
#!/bin/sh
npx eslint . --fix
再比如运行 Prettier 格式化:
#!/bin/sh
npx prettier --write .
注意:Husky 7 之后要求钩子脚本第一行必须是 #!/bin/sh,否则会在 Windows 上出问题。
实战二:多阶段提交前检查
一个项目通常不止一种检查。你可以把多个命令串起来:
#!/bin/sh
echo "🔍 运行 ESLint..."
npx eslint src/ --max-warnings=0
if [ $? -ne 0 ]; then
echo "❌ ESLint 检查失败,提交已中止"
exit 1
fi
echo "🎨 运行 Prettier..."
npx prettier --check .
if [ $? -ne 0 ]; then
echo "❌ 格式检查失败,提交已中止"
exit 1
fi
echo "✅ 全部检查通过!"
exit 0
这样每次提交前都会先跑 lint,再跑格式检查。任何一个环节出错,提交就会被拒绝。
实战三:提交信息格式校验
很多团队要求提交信息遵循特定格式,比如:
feat: 新增用户登录功能
fix: 修复支付回调超时问题
docs: 更新 API 文档
用 commit-msg 钩子可以实现自动校验:
#!/bin/sh
commit_msg=$(cat .git/COMMIT_EDITMSG)
if ! echo "$commit_msg" | grep -qE '^(feat|fix|docs|chore|refactor|test|style):'; then
echo "❌ 提交信息格式不正确"
echo "请使用: <类型>: <描述>"
echo "类型可选: feat, fix, docs, chore, refactor, test, style"
exit 1
fi
echo "✅ 提交信息格式正确"
exit 0
这个钩子会读取即将写入的提交信息,检查是否符合约定格式。不符合就直接拒绝提交。
配合 Conventional Commits 规范,后续自动生成 changelog 会方便很多。
实战四:pre-push 阻止不安全的推送
有时候你不想把某些分支推送到远程。比如在提交信息里加了 [WIP] 标记的半成品代码。
#!/bin/sh
echo "🚀 检查推送内容..."
# 检查最近一次提交的 message
last_commit=$(git log -1 --pretty=%B)
if echo "$last_commit" | grep -qi "WIP"; then
echo "❌ 检测到 WIP 标记,禁止推送"
echo "请完成工作后再推送"
exit 1
fi
echo "✅ 推送检查通过"
exit 0
这个钩子在 push 之前运行,如果发现提交信息包含 WIP,就会直接拦截。
团队协作的配置共享
钩子脚本存在 .git/hooks/ 里是本地仓库的配置,不会随代码同步到其他开发者机器上。
解决办法是把钩子脚本放在项目仓库里,比如 .husky/ 或 .githooks/ 目录,然后通过 Husky 或其他工具在安装时自动链接到 .git/hooks/。
在 package.json 里加一段配置:
{
"husky": {
"hooks": {
"pre-commit": "npm run lint",
"commit-msg": "node scripts/validate-commit-msg.js",
"pre-push": "npm test"
}
}
}
新成员 clone 代码后运行 npm install,Husky 会自动安装钩子,不需要手动配置。
常见坑和避坑指南
第一个坑:钩子脚本没有执行权限。 确保所有钩子文件都是可执行的。如果用 Shell 写,记得 chmod +x。
第二个坑:Windows 上的换行符问题。 Windows 用 CRLF,Unix 用 LF。钩子脚本第一行的 shebang 如果换行符不对,Git 可能无法正确识别解释器。统一用 LF 格式保存脚本文件。
第三个坑:钩子执行超时。 如果某个检查特别耗时,比如跑完整的测试套件,可能会卡住提交流程。建议把耗时操作放到 CI/CD 流水线里,钩子里只做快速检查。
第四个坑:忽略钩子的情况。 有人会用 git commit --no-verify 跳过钩子。这不是 bug,是功能。遇到紧急情况需要绕过检查时可以用,但事后一定要补上缺失的检查。
总结
Git Hooks 是个被严重低估的功能。它不需要额外安装服务,不依赖外部系统,就在你的代码仓库里直接生效。
从简单的格式检查到复杂的自动化流程,Git Hooks 都能胜任。配合 Husky 这样的工具,配置过程也变得简单多了。
花半小时搭好钩子,能帮你省下无数小时的人工审查时间。
要不要现在就去项目里试一下?