pre-commit 钩子是什么
pre-commit 是 Git 在「生成提交文本之前」触发的本地钩子,用来把明显问题挡在提交之外:代码格式化、静态检查、敏感串扫描、大文件拦截。设计原则是快(秒级)、只针对暂存区、失败可局部复跑;耗时长的检查放到 pre-push 或 CI,避免拖慢每一次提交。
基本信息
| 触发时点 | git commit 生成提交前,可用 --no-verify 跳过 |
|---|---|
| 常用内容 | 格式化工具、lint、密钥扫描、禁止提交大文件 |
| 输入范围 | 暂存区内容(git diff --cached) |
| 安装位置 | .git/hooks/pre-commit,或由 pre-commit 框架托管 |
| 失败表现 | 钩子非零退出即中止提交,修复后重试 |
典型使用场景
- 团队统一格式化:提交前自动跑 formatter,减少风格争论与 diff 噪声。
- 密钥扫描:拦截误提交的令牌、私钥;配合全历史扫描更稳。
- 大文件拦截:防止二进制产物或数据集塞进仓库历史。
- 快速静态检查:抓语法级错误与明显问题,比 CI 反馈更快。
- 提交信息校验:交给 commit-msg 钩子,格式不合格直接拦下。
- локальный 保护:禁止直接往受保护分支提交的团队约定检查。
钩子示例
钩子示例
#!/bin/sh
set -e
# 取暂存区里新增/修改的 js、ts 文件
files=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(js|ts)$' || true)
[ -z "$files" ] && exit 0
# 只对涉及的文件跑检查,有警告即失败
echo "$files" | xargs -r npx eslint --max-warnings=0钩子选择对照
| 钩子 | 时机 | 适合内容 |
|---|---|---|
| pre-commit | 提交前 | 秒级检查:格式化、lint、密钥扫描 |
| commit-msg | 信息定稿前 | 提交信息格式校验 |
| pre-push | 推送前 | 单元测试、类型检查等较慢项 |
| pre-rebase | 变基前 | 阻止对已共享提交做变基 |
只检查暂存区内容最符合直觉:用 git diff --cached 取文件列表,避免把未暂存改动一起判罚。钩子文件默认不随克隆分发,团队要么用 pre-commit 框架,要么提供仓库内安装脚本;统一用框架管理钩子版本,避免各自手装不一致。