使用 Git Pre-commit Hook 实现代码自动检查
深入了解 Git pre-commit 钩子的工作原理、团队共享钩子的最佳实践,以及在提交前自动进行代码格式化与校验。
想象一下:你刚刚写完一段出色的代码,兴奋地执行 git commit 并推送到远程仓库,几分钟后 CI/CD 构建却因漏掉的分号或格式问题宣告失败。
这种场景屡见不鲜。如何才能在本地提交前就拦截这些小错误?答案就是 Git Pre-commit Hook。
什么是 Git Pre-commit Hook#
Git Hooks 是 Git 内置的自动化脚本机制,允许在 Git 工作流的关键节点(如提交前、推送前或切换分支后)自动触发脚本。
其中 pre-commit 钩子 在运行 git commit 命令后、Git 生成提交对象前立即执行。如果脚本的退出码不为 0(退出码 != 0),提交过程将被立即终止。
graph LR
A[执行 git commit] --> B{Pre-commit Hook}
B -->|退出码 = 0| C[提交成功]
B -->|退出码 != 0| D[中断提交并报错]
钩子共享难题与 core.hooksPath#
默认情况下,Git 钩子存放在隐藏的 .git/hooks/ 目录中。然而,.git 目录 不会纳入版本控制。这导致了两个明显痛点:
- 团队难以共享:每位成员都需要手动将脚本复制到各自的
.git/hooks/目录。 - 容易遗漏:新成员加入项目时常常忘记配置本地钩子。
使用 core.hooksPath 解决方案#
自 Git 2.9 起,Git 提供了 core.hooksPath 配置项,允许自定义钩子的存放路径。
我们可以将所有钩子统一管理在版本控制的目录中(例如 .githooks/),并进行如下配置:
git config core.hooksPath .githooksbash在 Node.js 或 Bun 项目中,可通过 package.json 中的 prepare 脚本实现自动化配置:
{
"scripts": {
"prepare": "git config core.hooksPath .githooks"
}
}json每当团队成员运行 npm install 或 bun install 时,Git 会自动配置使用项目根目录下的 .githooks。
实战示例:使用 agent-md 自动格式化 Markdown#
以下是一个真实的 pre-commit 脚本示例:自动检查系统是否存在 agent-md CLI 工具,若存在则对暂存区中的 Markdown 文件进行格式化并重新暂存:
#!/usr/bin/env bash
# 1. 检查系统中是否存在 agent-md CLI
if command -v agent-md >/dev/null 2>&1; then
# 2. 获取已暂存的 Markdown 文件列表(排除已删除文件)
STAGED_MD_FILES=$(git diff --cached --name-only --diff-filter=d | grep -E '\.(md|mdx)$')
if [ -n "$STAGED_MD_FILES" ]; then
echo "[git-hook] 正在使用 agent-md 自动格式化暂存的 Markdown 文件..."
for file in $STAGED_MD_FILES; do
if [ -f "$file" ]; then
agent-md "$file"
git add "$file"
fi
done
fi
fibash切记为脚本赋予可执行权限:
chmod +x .githooks/pre-commitbash必要时跳过 Pre-commit Hook#
在紧急情况下(例如临时保存未完成的工作以切换分支),可以使用 --no-verify(或 -n)标志跳过钩子检查:
git commit -m "WIP: 临时保存" --no-verifybash[!TIP] 建议谨慎使用
--no-verify,以保持整个项目代码质量的一致性。