回退一次坏 commit,得强推、跑挂 CI,还得在群里说一句”抱歉,我的锅”。提交前自查只要 60 秒。问题从来不是这步值不值,而是太麻烦。一个能一键读取 staged diff 的 AI Agent 把麻烦去掉了,这步才真的会做。
这不是 PR review,而是你给自己工作做的那道便宜过滤——在别人看到之前先过一遍。
一句话总结
- 把一段 review prompt 绑到单个命令上(Claude Code 里的
/precommit、Cursor 里的保存 prompt),让它读git diff --staged。 - 范围只圈五类具体问题:遗留调试代码、硬编码密钥、null/undefined bug、off-by-one 错误、永远不该提交的文件。
- 下面再叠一层确定性的密钥扫描器(
gitleaks git --staged,截至 2026 年 6 月为 v8.30.1)——AI 抓逻辑味道,gitleaks 一个 API key 都不放过。 - 整个过程 60 秒,每次大概一两个真问题,其余是噪声,靠判断力筛。
这篇适合谁看
每天 commit 5 次以上的人,独立开发者尤其。下游没有队友时,你的 staged diff 就是进 main 前的最后一道关。当 diff 是 AI Agent(Claude Code、Cursor、Codex)写的时候,这套流程更值——Agent 生成的代码常带着”看起来很自信”的 bug,集中再读一遍很快就能逮住。
什么时候可以跳过:随手改的 typo、没人看的私有 WIP 分支。把这 60 秒花在会上线的分支上。
具体步骤
核心就是一键,配一次就好。
1. 建命令。 在 Claude Code 里,自定义 slash command 就是放在 .claude/commands/(项目级、纳入版本控制)或 ~/.claude/commands/(个人级)的 Markdown 文件。新建 .claude/commands/precommit.md:
---
description: commit 前 review staged diff
allowed-tools: Bash(git diff:*), Bash(git status:*)
---
跑 `git diff --staged`,只看将要 commit 的内容。
只标这些,附文件名和行号:
- 遗留调试代码:console.log、debugger、dbg!()、未藏在 flag 后的 print/printf、注释掉的代码块
- 硬编码的密钥、API key、token、连接字符串
- null / undefined / 类型错误,以及没处理的错误路径
- 循环和切片里的 off-by-one 或边界错
- 不该上线的文件:.env、.DS_Store、构建产物、大体积二进制文件
不要标风格、命名、重构建议。没问题就用一行回复 "clean"。
在 Cursor 里,把同样的 prompt 正文存成可复用片段或 .cursor/rules 条目,在对话里附上 staged diff 调用即可。
2. 精确 stage 你要提交的东西。 用 git add -p,让 Agent 看到的是真正的 diff,而不是 staged 和 unstaged 混在一起。在没 stage 的改动上 review 是最常见的翻车点——Agent 会标那些你根本不打算提交的行。
3. 跑命令。 输入 /precommit。Agent 读 git diff --staged,返回一份简短的标记清单。
4. 分流。 大多数标记是噪声,一两个通常是真问题。当场修真的那几个,git add 修改,如果又 stage 了新东西就再跑一遍。
5. 自己带着意图 commit。 别让 Agent 去跑 git commit。commit message 和”是否上线”的决定,归你。
配一个确定性的密钥扫描器
LLM 擅长看逻辑味道,不擅长做到无遗漏——累的时候再读一遍,可能就漏掉一个密钥。所以用一个永远不会累的工具兜底。Gitleaks(v8.30.1,2026 年 3 月发布)只扫 staged diff,命中就非零退出,直接拦下 commit:
gitleaks git --staged --verbose
注意 protect --staged 这种写法在 v8.19.0 已被弃用,现在的命令是 git --staged。几百行的 diff 远在一秒内就跑完。
把两者都接进 pre-commit hook,才算真自动化。用 Lefthook(比 Husky 快,因为它并行跑任务),写 lefthook.yml:
pre-commit:
parallel: true
commands:
secrets:
run: gitleaks git --staged --verbose
lint:
glob: "*.{js,ts,tsx}"
run: npm run lint -- {staged_files}
跑一次 lefthook install。从此每次 git commit 都会自动跑 gitleaks 和 lint;AI review 仍保持手动调 /precommit,因为判断这件事不该做成一道硬卡的闸。
| 层 | 工具 | 抓什么 | 是否拦截 |
|---|---|---|---|
| 确定性 | gitleaks git --staged | 所有密钥 / key 模式 | 是(hook) |
| 确定性 | ESLint / Biome(经 Lefthook) | lint 和类型味道 | 是(hook) |
| 判断力 | AI Agent /precommit | 逻辑 bug、off-by-one、遗留调试 | 否(手动) |
按你的技术栈定制清单
默认 prompt 是语言无关的,收紧它:
- Rust: 加
dbg!()、对可失败调用乱用的.unwrap()、忘删的#[allow(dead_code)]。 - TypeScript: 加
any类型、非空断言(!)、没写理由的@ts-ignore。 - Python: 加裸
except:、print()调试、breakpoint()。 - Go: 加
fmt.Println调试、被忽略的错误(_ =)。
那句”不要标”务必保留。少了它,Agent 会跑去提命名和重构建议,标记清单越滚越长,你就不看了——这正好把整件事的意义抵消掉。
实际怎么用
一个真实的周五傍晚:在 staged diff 上跑 /precommit,标出一个忘删的 debugger 和一个被 git add . 顺手扫进来的 .env。20 秒内都修好,干净地 commit,没留下周末事故。如果这次 commit 马上要发到 Firebase Hosting,紧接着跑一遍AI Firebase 部署检查工作流,在上线前抓出 rewrite 顺序和 region 问题。
FAQ
- 它能取代 PR code review 吗?:不能。它是你自己 commit 的预过滤,在别人看之前先跑。真正的 review 仍发生在 PR 阶段,由懂这个功能意图的人来做。
- 60 秒的检查不会拖慢我吗?:就 60 秒,密钥扫描更是亚秒级。第一次它抓到一个被提交的
.env或 API key,就够回本一整年——轮换泄露的 key、重写 git 历史,要花几个小时。 - 该用哪个模型做 review?:任何当前一线模型都能轻松处理一小段 staged diff。Claude Code 只跑 Anthropic 模型(这个任务 Sonnet 4.6 足够,大 diff 用 Opus 4.7);Cursor 里可选 Sonnet 4.6、GPT-5.5 或 Gemini 3.1 Pro。任务很小,模型选择影响很小,按键速度才更重要。
- 密钥也直接交给 AI 不行吗?:不行。LLM 是概率性的,长 diff 上可能漏一个 key。gitleaks 基于正则和熵,是确定性的,不会有状态不好的时候。判断交给 AI,覆盖交给扫描器。
- 能让 Agent 替我 commit 吗?:不要。把
git commit留在自己手里,message 和意图都归你。让 Agent 负责 review,不负责拍板。