Skip to content

钩子管理工具

手动管理 Git 钩子存在诸多不便:无法纳入版本控制、团队成员需要手动配置。钩子管理工具解决了这些问题,让团队的 Git 钩子自动安装和共享。

Husky(Node.js 项目)

Husky 是 Node.js 项目中最流行的 Git 钩子管理工具。

安装配置

bash
# 安装 Husky
npm install --save-dev husky

# 初始化(在 package.json 中添加 prepare 脚本)
npx husky init

# 这会创建 .husky/ 目录和配置

package.json 配置:

json
{
  "scripts": {
    "prepare": "husky"
  },
  "devDependencies": {
    "husky": "^9.0.0"
  }
}

创建钩子

bash
# 创建 pre-commit 钩子
echo "npm run lint" > .husky/pre-commit
chmod +x .husky/pre-commit

# 创建 commit-msg 钩子
echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg
chmod +x .husky/commit-msg

.husky/pre-commit 内容:

sh
#!/bin/sh
npm run lint
npm test

配合 lint-staged

lint-staged 只对暂存区的文件执行 lint,速度更快:

bash
npm install --save-dev lint-staged

package.json:

json
{
  "lint-staged": {
    "*.{js,ts,tsx}": ["eslint --fix", "prettier --write"],
    "*.{css,scss}": ["prettier --write"],
    "*.md": ["prettier --write"]
  }
}

.husky/pre-commit

sh
#!/bin/sh
npx lint-staged

配合 commitlint

commitlint 验证提交信息格式:

bash
npm install --save-dev @commitlint/cli @commitlint/config-conventional

commitlint.config.js:

js
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [2, 'always', [
      'feat', 'fix', 'docs', 'style', 'refactor',
      'perf', 'test', 'chore', 'ci', 'build', 'revert'
    ]],
    'subject-max-length': [2, 'always', 72],
    'subject-case': [0]  // 不限制大小写(支持中文)
  }
};

.husky/commit-msg

sh
#!/bin/sh
npx --no -- commitlint --edit "$1"

pre-commit(Python 项目)

pre-commit 是跨语言的钩子管理工具,支持多种语言的钩子。

安装

bash
# 使用 pip 安装
pip install pre-commit

# 或使用 Homebrew
brew install pre-commit

配置

在项目根目录创建 .pre-commit-config.yaml

yaml
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.5.0
    hooks:
      - id: trailing-whitespace    # 清除行尾空格
      - id: end-of-file-fixer      # 确保文件以换行符结尾
      - id: check-yaml             # 检查 YAML 语法
      - id: check-json             # 检查 JSON 语法
      - id: check-merge-conflict   # 检查合并冲突标记
      - id: check-added-large-files  # 阻止大文件

  - repo: https://github.com/psf/black
    rev: 23.12.0
    hooks:
      - id: black  # Python 代码格式化

  - repo: https://github.com/pycqa/flake8
    rev: 7.0.0
    hooks:
      - id: flake8  # Python 代码检查

  - repo: https://github.com/commitizen-tools/commitizen
    rev: v3.13.0
    hooks:
      - id: commitizen  # 提交信息规范检查

安装和使用

bash
# 安装钩子(会配置 .git/hooks/pre-commit 等)
pre-commit install

# 安装 commit-msg 钩子
pre-commit install --hook-type commit-msg

# 手动运行(对所有文件)
pre-commit run --all-files

# 只对暂存文件运行
pre-commit run

# 更新所有 hook 到最新版
pre-commit autoupdate

lefthook

lefthook 是一个快速、跨语言的 Git 钩子管理工具:

安装

bash
# macOS
brew install lefthook

# Node.js 项目
npm install --save-dev lefthook

# 其他平台
# https://github.com/evilmartians/lefthook#install

配置

创建 lefthook.yml

yaml
# lefthook.yml
pre-commit:
  parallel: true
  commands:
    lint:
      glob: "*.{js,ts}"
      run: npx eslint {staged_files}
    format:
      glob: "*.{js,ts,css,md}"
      run: npx prettier --check {staged_files}
    test:
      run: npm test -- --watchAll=false

commit-msg:
  commands:
    check-format:
      run: npx commitlint --edit {1}

pre-push:
  commands:
    build:
      run: npm run build
bash
# 安装钩子
lefthook install

# 手动运行
lefthook run pre-commit

团队间共享钩子的方案

方案1:自定义 hooksPath(推荐)

bash
# 将钩子目录放入版本控制
mkdir -p scripts/hooks

# 创建钩子脚本
cat > scripts/hooks/pre-commit << 'EOF'
#!/bin/sh
npm run lint
EOF
chmod +x scripts/hooks/pre-commit

# 提交到仓库
git add scripts/hooks/
git commit -m "chore: 添加 Git 钩子脚本"

# 团队成员配置(可以放入 setup 脚本)
git config core.hooksPath scripts/hooks

**自动化安装:**在 package.jsonprepare 脚本中添加:

json
{
  "scripts": {
    "prepare": "git config core.hooksPath scripts/hooks && chmod +x scripts/hooks/*"
  }
}

方案2:使用 Husky/pre-commit/lefthook

这些工具的配置文件(.husky/.pre-commit-config.yamllefthook.yml)可以纳入版本控制,团队成员只需运行一次安装命令。

方案3:Makefile 或 setup 脚本

makefile
# Makefile
.PHONY: setup
setup:
    @echo "配置 Git 钩子..."
    @git config core.hooksPath scripts/hooks
    @chmod +x scripts/hooks/*
    @echo "✅ 设置完成"

工具选择建议

工具适合项目特点
HuskyNode.js 项目集成度高,社区庞大
pre-commitPython 项目 / 跨语言支持多种语言钩子
lefthook任意语言快速,支持并行执行
自定义 hooksPath小型项目简单直接,无额外依赖

总结

无论选择哪种工具,核心目标是一致的:

  1. 钩子配置纳入版本控制,团队共享
  2. 新成员克隆后简单操作即可完成安装
  3. 自动化代码质量检查,减少人工审查负担

Husky + lint-staged + commitlint 是 Node.js 项目的黄金组合,pre-commit 是 Python 和多语言项目的首选。