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 钩子的生命周期流程

八、最佳实践与注意事项
✅ 最佳实践
-
快速失败:检查失败时立即退出
-
提供明确错误信息:告诉用户如何修复
-
保持钩子轻量:避免长时间运行
-
团队共享:钩子配置应该纳入版本控制
-
可跳过机制:紧急情况下可以跳过
bash
git commit -m "紧急修复" --no-verify
❌ 常见陷阱
-
忘记添加执行权限
bash
chmod +x .git/hooks/pre-commit -
钩子中修改的文件不会被自动提交
-
不同操作系统兼容性问题(使用跨平台工具如 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 钩子的核心价值:
-
自动化:自动执行重复任务
-
标准化:确保团队代码质量一致
-
安全性:防止错误代码进入仓库
-
效率:减少人工检查时间
选择建议:
-
小型项目:直接使用原生 Git 钩子
-
前端/Node.js 项目:Husky + lint-staged
-
团队协作项目:添加 Commitlint 规范提交
-
企业级项目:结合 CI/CD 完整流程
Git 钩子是现代开发工作流的核心组件,正确使用可以显著提升代码质量和团队协作效率!