Git 钩子(Git Hooks)详解

Git 钩子(Git Hooks)详解


一、什么是 Git 钩子?

Git 钩子 是 Git 在特定事件发生时自动执行的自定义脚本。它们就像是 Git 工作流程中的"触发器"或"回调函数"。

简单比喻:

  • 红绿灯:提交代码前的检查

  • 安全警报:防止错误代码进入仓库

  • 自动化助手:自动执行重复任务


二、Git 钩子存储位置

bash

复制代码
# 查看所有钩子
ls -la .git/hooks/

# 输出示例:
applypatch-msg.sample     pre-applypatch.sample     pre-rebase.sample
commit-msg.sample         pre-commit.sample         prepare-commit-msg.sample
post-update.sample        pre-push.sample           update.sample

路径 :每个 Git 仓库的 .git/hooks/ 目录


三、Git 钩子分类(按触发时机)

1. 客户端钩子(本地操作)

钩子名称 触发时机 主要用途
pre-commit git commit 执行 代码检查、格式化、测试
prepare-commit-msg 生成提交消息后,编辑器打开前 修改默认提交消息
commit-msg 提交消息编辑完成后 验证提交消息格式
post-commit 提交完成后 通知、记录、触发CI
pre-rebase git rebase 检查是否允许变基
post-checkout git checkout 设置环境、安装依赖
post-merge git merge 更新依赖、重建索引
pre-push git push 远程推送前的检查

2. 服务端钩子(服务器操作)

钩子名称 触发时机 主要用途
pre-receive 服务器接收推送前 检查提交、权限验证
update 每个分支更新前 细粒度分支控制
post-receive 推送完成后 部署、通知、触发构建

四、实际应用场景

场景1:代码质量检查(最常用)

bash

复制代码
#!/bin/sh
# .git/hooks/pre-commit

echo "🚀 运行代码检查..."

# 1. 运行 ESLint
npm run lint
if [ $? -ne 0 ]; then
  echo "❌ ESLint 检查失败"
  exit 1
fi

# 2. 运行测试
npm test
if [ $? -ne 0 ]; then
  echo "❌ 测试失败"
  exit 1
fi

# 3. 代码格式化
npx prettier --write "src/**/*.js"

echo "✅ 检查通过,可以提交!"

场景2:提交信息规范

bash

复制代码
#!/bin/sh
# .git/hooks/commit-msg

# 检查提交信息格式(遵循 Conventional Commits)
MSG=$(cat $1)
PATTERN="^(feat|fix|docs|style|refactor|test|chore)\(.*\): .{1,}"

if ! echo "$MSG" | grep -qE "$PATTERN"; then
  echo "❌ 提交信息格式错误!"
  echo "✅ 正确格式: type(scope): description"
  echo "✅ 示例: feat(auth): 添加用户登录功能"
  echo "❌ 你的提交: $MSG"
  exit 1
fi

场景3:自动部署

bash

复制代码
#!/bin/sh
# .git/hooks/post-receive (服务器上)

echo "🔄 开始部署..."

# 切换到项目目录
cd /var/www/myapp

# 拉取最新代码
git pull origin main

# 安装依赖
npm install --production

# 重启服务
pm2 restart myapp

echo "✅ 部署完成!"

五、如何使用 Git 钩子

方法1:手动创建(原生方式)

bash

复制代码
# 1. 进入钩子目录
cd .git/hooks

# 2. 创建 pre-commit 钩子
cat > pre-commit << 'EOF'
#!/bin/sh
echo "Running pre-commit checks..."
npm run lint
EOF

# 3. 添加执行权限
chmod +x pre-commit

方法2:使用 Husky(现代推荐)

bash

复制代码
# 1. 安装 Husky
npm install husky --save-dev

# 2. 启用 Git 钩子
npx husky install

# 3. 创建钩子(自动设置权限)
npx husky add .husky/pre-commit "npm test"
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'

# 4. package.json 中配置自动安装
{
  "scripts": {
    "prepare": "husky install"
  }
}

方法3:使用预提交框架

bash

复制代码
# 使用 pre-commit 框架
pip install pre-commit

# 创建配置文件 .pre-commit-config.yaml
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.3.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml

六、常见工具集成

代码检查组合拳

json

复制代码
{
  "scripts": {
    "prepare": "husky install",
    "lint": "eslint src --fix",
    "format": "prettier --write .",
    "test": "jest"
  }
}

bash

复制代码
# .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run lint-staged

json

复制代码
{
  "lint-staged": {
    "*.{js,ts}": ["eslint --fix", "prettier --write"],
    "*.{json,md}": ["prettier --write"]
  }
}

七、Git 钩子的生命周期流程


八、最佳实践与注意事项

✅ 最佳实践

  1. 快速失败:检查失败时立即退出

  2. 提供明确错误信息:告诉用户如何修复

  3. 保持钩子轻量:避免长时间运行

  4. 团队共享:钩子配置应该纳入版本控制

  5. 可跳过机制:紧急情况下可以跳过


    bash

    复制代码
    git commit -m "紧急修复" --no-verify

❌ 常见陷阱

  1. 忘记添加执行权限

    bash

    复制代码
    chmod +x .git/hooks/pre-commit
  2. 钩子中修改的文件不会被自动提交

  3. 不同操作系统兼容性问题(使用跨平台工具如 Husky)


🌐 现代化工具栈

工具 用途 特点
Husky 管理 Git 钩子 配置简单,跨平台
lint-staged 只检查暂存文件 速度快,效率高
Commitlint 提交信息规范检查 支持 Conventional Commits
pre-commit Python 项目钩子管理 多语言支持

九、实际项目配置示例

复制代码
// package.json
{
  "scripts": {
    "prepare": "husky install",
    "lint": "eslint . --ext .js,.jsx,.ts,.tsx",
    "format": "prettier --write .",
    "test": "jest --passWithNoTests"
  },
  "devDependencies": {
    "husky": "^8.0.0",
    "lint-staged": "^13.0.0",
    "@commitlint/cli": "^17.0.0",
    "@commitlint/config-conventional": "^17.0.0"
  },
  "lint-staged": {
    "*.{js,jsx,ts,tsx}": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.{json,md,yml,yaml}": [
      "prettier --write"
    ]
  }
}

bash

复制代码
# .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged

bash

复制代码
# .husky/commit-msg
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx --no -- commitlint --edit "$1"

十、总结

Git 钩子的核心价值:

  1. 自动化:自动执行重复任务

  2. 标准化:确保团队代码质量一致

  3. 安全性:防止错误代码进入仓库

  4. 效率:减少人工检查时间

选择建议:

  • 小型项目:直接使用原生 Git 钩子

  • 前端/Node.js 项目:Husky + lint-staged

  • 团队协作项目:添加 Commitlint 规范提交

  • 企业级项目:结合 CI/CD 完整流程


Git 钩子是现代开发工作流的核心组件,正确使用可以显著提升代码质量和团队协作效率!