本文目录导读:

Git 钩子脚本检查质量门禁的核心思路是:在提交或推送代码之前,自动运行一系列检查命令,如果检查失败则阻止操作(返回非零退出码)。
以下是实现这一目标的几种常见方法和具体脚本示例:
核心原理
- 退出码:脚本若返回
0,允许操作;返回非0(如1),拒绝操作。 - 钩子类型:
pre-commit:在生成提交前运行,适合对即将暂存的文件进行检查。pre-push:在推送到远程前运行,适合运行更全面、耗时更长的检查。
常见质量门禁检查项
- 代码格式(ESLint/Prettier/Ruff)
- 代码规范 / 类型检查(TypeScript / mypy)
- 单元测试(仅对修改的文件运行)
- 安全扫描(Secret 泄露检查)
- 文件大小限制(避免提交大文件)
- 分支命名规范
具体脚本示例(Shell + Node.js 环境)
示例 1:pre-commit — 仅对暂存文件运行 ESLint 和 Prettier
#!/bin/sh # .git/hooks/pre-commit # 获取所有暂存 .js/.ts/.jsx/.tsx 文件 STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(js|ts|jsx|tsx)$') if [ -z "$STAGED_FILES" ]; then echo "✅ No staged JS/TS files to lint." exit 0 fi echo "🔍 Running ESLint on staged files..." # 针对暂存文件运行 ESLint,只报告错误(--quiet),若失败则终止 npx eslint $STAGED_FILES --quiet if [ $? -ne 0 ]; then echo "❌ ESLint failed. Fix errors and re-add files." exit 1 fi echo "🎨 Running Prettier check on staged files..." npx prettier --check $STAGED_FILES if [ $? -ne 0 ]; then echo "❌ Prettier check failed. Run 'npx prettier --write' and re-add." exit 1 fi echo "✅ All checks passed!" exit 0
示例 2:pre-push — 运行完整测试和类型检查
#!/bin/sh # .git/hooks/pre-push echo "🏗️ Running TypeScript type check..." npx tsc --noEmit if [ $? -ne 0 ]; then echo "❌ TypeScript errors found. Fix before pushing." exit 1 fi echo "🧪 Running all unit tests..." npm test -- --watchAll=false if [ $? -ne 0 ]; then echo "❌ Some tests failed. Fix and commit again." exit 1 fi echo "🛡️ Running secret scan (truffleHog example)..." # 假设已安装 trufflehog trufflehog git file://. --since-commit HEAD~1 --fail if [ $? -ne 0 ]; then echo "❌ Secret detected in recent commits!" exit 1 fi echo "✅ All pre-push checks passed!" exit 0
示例 3:pre-commit — 检查暂存文件大小(避免提交大文件)
#!/bin/sh
# .git/hooks/pre-commit
echo "📏 Checking file size limits..."
MAX_SIZE_MB=5
LIMIT=$((MAX_SIZE_MB * 1024 * 1024))
git diff --cached --name-only -z | while IFS= read -r -d '' file; do
if [ -f "$file" ]; then
size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null)
if [ "$size" -gt "$LIMIT" ]; then
echo "⚠️ Error: '$file' is ${size}B, exceeds ${MAX_SIZE_MB}MB limit."
exit 1
fi
fi
done
if [ $? -ne 0 ]; then
exit 1
fi
echo "✅ All file sizes OK."
exit 0
高级工具:Husky + lint-staged
如果你使用 npm/yarn,最现代的方案是利用 Husky 和 lint-staged 自动管理钩子。
安装:
npx husky init npm install --save-dev lint-staged
配置 package.json:
{
"lint-staged": {
"*.{js,ts,tsx}": ["eslint --fix", "prettier --write"],
"*.{css,md}": ["prettier --write"]
}
}
创建钩子(由 Husky 管理):
npx husky set .husky/pre-commit "npx lint-staged" npx husky set .husky/pre-push "npm test && npx tsc --noEmit"
优点:
- 钩子自动安装(
husky install可自动配置git config core.hooksPath) lint-staged只处理暂存文件,速度极快- 团队成员无需手动复制
.git/hooks文件
关键注意事项
| 问题 | 解决方案 |
|---|---|
| 跳过检查 | 用户可以使用 git commit --no-verify 或 git push --no-verify 跳过钩子,钩子无法强制避免。 |
| 大量暂存文件 | 尽量只对暂存文件运行检查,不要对所有文件运行。 |
| 脚本运行时间 | 对于耗时操作(如全量测试),应放在 pre-push,而非 pre-commit。 |
| 跨平台兼容 | 尽量使用 Node.js 脚本(通过 shebang #!/usr/bin/env node)而非纯 Shell,以兼容 Windows。 |
| 版本控制 | 将钩子脚本放在项目仓库的 scripts/git-hooks/ 目录中(或 .husky/),并通过安装脚本或 husky install 让团队自动启用。 |
如何分发这些脚本给团队?
-
仓库内存储:将
.sh脚本放在scripts/git-hooks/下。 -
自动安装:在
package.json的postinstall或项目的初始化脚本中执行以下命令:# 配置 Git 使用自定义钩子目录 git config core.hooksPath scripts/git-hooks
-
使用 Husky(推荐):Husky 会自动处理钩子路径,团队只需
npm install即可。
- 基础方法:编写
.sh脚本放在.git/hooks/中,手动复制(不推荐生产环境)。 - 现代方法:使用 Husky + lint-staged,只需一个
npm install即可为全团队配置好质量门禁。 - 核心原则:只在暂存文件上运行检查、合理区分
pre-commit(快速)和pre-push(全面)、接受用户可使用--no-verify跳过。
你目前的项目使用什么语言和包管理器(如 npm、yarn、pip 等)?我可以提供更具体的配置示例。