本文目录导读:

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 等)?我可以提供更具体的配置示例。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播