SuperAPI AI 工具集

git-hooks

编程与开发

查看项目

更新于 10-15 07:47

技能介绍

用途

Git Hooks 用于通过 Git 钩子自动化代码质量检查、强制执行约定,并阻止不良提交进入仓库。它适用于希望在本地提交与推送阶段就完成 lint、格式化、密钥扫描、提交信息校验等工作的开发流程。

钩子类型与用途

资料给出的钩子类型及常见用途对照:

  • pre-commit:在创建提交之前触发,常见用途为 lint、格式化、密钥扫描。
  • prepare-commit-msg:在默认信息生成后、编辑前触发,常见用途为添加工单 ID、模板。
  • commit-msg:在用户写完提交信息后触发,常见用途为强制 Conventional Commits。
  • pre-push:在推送到远端之前触发,常见用途为完整测试套件、构建检查。
  • pre-rebase:在变基开始前触发,常见用途为防止对受保护分支进行变基。
  • post-merge:在合并完成后触发,常见用途为重装依赖、运行迁移。
  • post-checkout:在检出/切换后触发,常见用途为重新构建、清理缓存。

主要工具与配置方式

Husky v9(Node.js 项目)

安装与初始化命令:

npm install -D husky
npx husky init

初始化会创建带 pre-commit 钩子的 .husky/ 目录,并在 package.json 中添加 "prepare": "husky"。创建钩子时,每个钩子都是普通 shell 脚本,例如:

echo "npx lint-staged" > .husky/pre-commit
echo "npm test" > .husky/pre-push
echo 'npx --no -- commitlint --edit "$1"' > .husky/commit-msg

v9 与 v8 的关键差异:不再需要 source husky.sh,钩子是普通脚本;内部通过 "prepare" 脚本使用 core.hooksPath;如果克隆后钩子不运行,可执行 npm run prepare。

lint-staged 配置

JSON 配置示例:

{
  "lint-staged": {
    "*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"],
    "*.{json,md,yml,yaml}": "prettier --write",
    "*.css": ["stylelint --fix", "prettier --write"],
    "*.py": ["ruff check --fix", "ruff format"],
    "*.go": ["gofmt -w", "go vet ./..."]
  }
}

函数式配置(lint-staged.config.mjs)可针对改动文件范围运行命令,例如任意 TS 文件变化时对整个项目运行 tsc --noEmit、显式传入文件名、只运行相关测试(jest --findRelatedTests)。

Lefthook(现代替代方案)

安装与初始化:

npm install -D lefthook    # 或: brew install lefthook
npx lefthook install

lefthook.yml 可声明 pre-commit(并行执行 lint、format、types)、commit-msg(validate)、pre-push(test)。资料列出 Lefthook 优势:YAML 配置、内置并行执行、glob 过滤、{staged_files} 变量、Go 二进制(无 Node 依赖)、原生 monorepo root: 支持。

pre-commit 框架(Python/多语言)

安装:

pip install pre-commit
pre-commit install
pre-commit install --hook-type pre-push

.pre-commit-config.yaml 可引用官方钩子仓库(trailing-whitespace、end-of-file-fixer、check-yaml、check-added-large-files、detect-private-key、check-merge-conflict)、ruff-pre-commit,以及本地钩子(如 pytest,stages: [pre-push])。常用命令:pre-commit run --all-files、pre-commit autoupdate。

自定义钩子脚本

资料提供多类自定义脚本示例:

  • Conventional Commits 强制校验(commit-msg 中匹配 type(scope): description 格式,不符合则报错退出)。
  • 分支命名强制(pre-push 中校验 feature/bugfix/hotfix/release/chore 前缀)。
  • 密钥检测(pre-commit 扫描暂存文件的敏感模式)。
  • 文件大小限制(pre-commit 阻止超过 1MB 的文件)。
  • 合并冲突标记检查(pre-commit 阻止含 <<<<<<<、=======、>>>>>>> 的文件)。
  • Node.js 版 commit-msg 与 Python 版 pre-commit(语法检查暂存 Python 文件)示例。

团队共享钩子

  • Husky:钩子位于 .husky/,通过 "prepare": "husky" 自动安装。
  • core.hooksPath:与语言无关,创建 .githooks 并 chmod +x,再执行 git config core.hooksPath .githooks;可通过 scripts 的 prepare 自动执行该配置。
  • 共享 .gitconfig(开发者自愿启用):提交含 [core] hooksPath = .githooks 的 .gitconfig,开发者运行 git config --local include.path ../.gitconfig。

跳过钩子

git commit --no-verify -m "hotfix: emergency production fix"
git push --no-verify

资料说明:适用于紧急热修复、WIP 提交、钩子损坏阻塞工作;不适用于经常跳过失败测试、绕过密钥检测。

调试钩子

git config core.hooksPath          # 查看当前钩子目录(空表示 .git/hooks/)
git rev-parse --git-path hooks     # 解析后的路径
bash -x .husky/pre-commit          # 追踪执行
chmod +x .githooks/pre-commit      # 修复权限

常见问题:缺少 chmod +x、shebang 错误、nvm 未加载(钩子不 source .bashrc)、core.hooksPath 错误。nvm 修复方式为在钩子中加入 export NVM_DIR="$HOME/.nvm" && . "$NVM_DIR/nvm.sh";调试环境变量可临时加入 env > /tmp/hook-env.txt。

Monorepo 模式

  • Lefthook monorepo:通过 root: packages/frontend/ 与 root: packages/backend/ 分别运行前端与后端 lint。
  • lint-staged monorepo:根配置中按包路径匹配并 cd 到对应目录执行命令。
  • 仅测试受影响包的 pre-push 脚本:通过 git diff --name-only @{push}.. 判断哪些包发生变化并分别运行测试。

CI/CD 钩子等价物

资料给出 GitHub Actions 工作流示例:在 push、pull_request 时运行 npm ci、eslint、prettier --check、npm test、commitlint,作为本地钩子的 CI 端安全网。

适用场景与限制

适用于需要在提交与推送阶段统一代码质量与提交规范的团队,以及使用 Node.js、Python 或多语言仓库的项目。资料未提供具体收费、价格或平台支持信息。跳过钩子(--no-verify)应仅限特定情形,不应作为常规做法。