Git钩子脚本如何检查质量门禁

wen 实用脚本 1

本文目录导读:

Git钩子脚本如何检查质量门禁

  1. 核心原理
  2. 常见质量门禁检查项
  3. 具体脚本示例(Shell + Node.js 环境)
  4. 高级工具:Husky + lint-staged
  5. 关键注意事项
  6. 如何分发这些脚本给团队?

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,最现代的方案是利用 Huskylint-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-verifygit push --no-verify 跳过钩子,钩子无法强制避免
大量暂存文件 尽量只对暂存文件运行检查,不要对所有文件运行。
脚本运行时间 对于耗时操作(如全量测试),应放在 pre-push,而非 pre-commit
跨平台兼容 尽量使用 Node.js 脚本(通过 shebang #!/usr/bin/env node)而非纯 Shell,以兼容 Windows。
版本控制 将钩子脚本放在项目仓库的 scripts/git-hooks/ 目录中(或 .husky/),并通过安装脚本或 husky install 让团队自动启用。

如何分发这些脚本给团队?

  1. 仓库内存储:将 .sh 脚本放在 scripts/git-hooks/ 下。

  2. 自动安装:在 package.jsonpostinstall 或项目的初始化脚本中执行以下命令:

    # 配置 Git 使用自定义钩子目录
    git config core.hooksPath scripts/git-hooks
  3. 使用 Husky(推荐):Husky 会自动处理钩子路径,团队只需 npm install 即可。


  • 基础方法:编写 .sh 脚本放在 .git/hooks/ 中,手动复制(不推荐生产环境)。
  • 现代方法:使用 Husky + lint-staged,只需一个 npm install 即可为全团队配置好质量门禁。
  • 核心原则:只在暂存文件上运行检查、合理区分 pre-commit(快速)和 pre-push(全面)、接受用户可使用 --no-verify 跳过。

你目前的项目使用什么语言和包管理器(如 npm、yarn、pip 等)?我可以提供更具体的配置示例。

抱歉,评论功能暂时关闭!