blog.dopana

Back

想象一下:你刚刚写完一段出色的代码,兴奋地执行 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 目录 不会纳入版本控制。这导致了两个明显痛点:

  1. 团队难以共享:每位成员都需要手动将脚本复制到各自的 .git/hooks/ 目录。
  2. 容易遗漏:新成员加入项目时常常忘记配置本地钩子。

使用 core.hooksPath 解决方案#

自 Git 2.9 起,Git 提供了 core.hooksPath 配置项,允许自定义钩子的存放路径。

我们可以将所有钩子统一管理在版本控制的目录中(例如 .githooks/),并进行如下配置:

git config core.hooksPath .githooks
bash

在 Node.js 或 Bun 项目中,可通过 package.json 中的 prepare 脚本实现自动化配置:

package.json
{
  "scripts": {
    "prepare": "git config core.hooksPath .githooks"
  }
}
json

每当团队成员运行 npm installbun install 时,Git 会自动配置使用项目根目录下的 .githooks

实战示例:使用 agent-md 自动格式化 Markdown#

以下是一个真实的 pre-commit 脚本示例:自动检查系统是否存在 agent-md CLI 工具,若存在则对暂存区中的 Markdown 文件进行格式化并重新暂存:

切记为脚本赋予可执行权限:

chmod +x .githooks/pre-commit
bash

必要时跳过 Pre-commit Hook#

在紧急情况下(例如临时保存未完成的工作以切换分支),可以使用 --no-verify(或 -n)标志跳过钩子检查:

git commit -m "WIP: 临时保存" --no-verify
bash

[!TIP] 建议谨慎使用 --no-verify,以保持整个项目代码质量的一致性。

参考资料#