Git Commit Message Prompt:写出团队能读懂的 commit
基于 git diff 生成符合 Conventional Commits 的提交信息,重点是逼模型补上 diff 里没有的 why;改动不相关时让它拒绝硬拼、要求拆分。六个月内 git blame 看得懂。
发布 2026-06-21更新 2026-10-17一句话解决什么问题:让 AI 写出「六个月后 git blame 时能看懂」的 commit message,而不是 Update auth.ts 这种废话。
难点不在格式(Conventional Commits 一页纸就写完),而在信息从哪来——diff 里有 what,没有 why。所以这套 prompt 真正的约束是逼模型去补 diff 里没有的东西,并在它补不出来时(多个不相关改动)让它拒绝硬拼、要求拆分。
适用场景:日常提交、批量迁移、开源项目贡献;也适合作为 prepare-commit-msg 钩子固化进团队流程。
用法
git add -p # stage 你想 commit 的部分
git diff --cached # 看 staged diff
把 diff 粘进 AI 配合 prompt:
Prompt
请基于下面的 git diff 生成 commit message,要求:
**格式**:Conventional Commits
```
<type>(<scope>): <subject>
<body>
<footer>
```
**type**:feat / fix / refactor / docs / test / chore / perf / style
**铁律**:
1. **subject ≤ 60 字符**,祈使句("add X" 不是 "added X")
2. **不要写"update XX 文件"**。要写**改了什么行为**。"update userService.ts" ❌;"add retry logic to userService.fetch" ✅
3. **body 解释 why,不是 what**——what 看 diff 就知道,why 看不出来
4. **如果是 fix,body 必须说**:(a) 现象、(b) 根本原因、(c) 修复方式
5. **scope 取自 diff 涉及的目录/模块**,不要瞎编
6. **如果 diff 包含多个不相关改动**,告诉我"建议拆成 N 个 commit",**不要硬拼成一条 message**
diff:
```
<paste here>
```
为什么有效
- "解释 why 不是 what"是核心——好 commit message 让 6 个月后
git blame的人能立刻理解决策 - "建议拆 commit"防止 AI 把混乱的 diff 强行总结成一条空泛的 message
- 对 fix 强制"现象 / 根因 / 修复"三段式 = 直接可读的事故记录
进阶(自动化)
把这个 prompt 存成 .git/hooks/prepare-commit-msg 或 claude-code 的别名脚本:
# ~/.local/bin/aicommit
git diff --cached | claude-code --prompt-file=~/.config/claude/commit-prompt.md \
| tee /tmp/msg && git commit -F /tmp/msg
跑 aicommit 就 = 自动 staged diff → AI 写 message → commit。
反例(AI 默认会写的烂 message)
Update auth.ts and config.tsVarious improvementsFix bug (fix 什么 bug?)
feat: add new feature(什么 feature?)
我们要的好例子:
fix(auth): handle 401 from token refresh endpointrefactor(api): extract pagination logic into useCursor hookfeat(rankings): add real-time tool ranking from db click counts
三种常见变体
① 中文团队(正文用中文,type/scope 保留英文)
格式同上,但:type 与 scope 保持英文(便于工具解析),subject 与 body 用中文。
subject ≤ 30 个汉字(约等于 60 字符的视觉宽度)。
好处是 git log --grep="feat" 这类自动化筛选不受影响,而正文对国内同事零阅读成本。
② Monorepo(scope 强制取包名)
scope 必须取自 diff 触及的 package 名(packages/<name> 或 apps/<name>),
不要用目录片段。若一次改动触及 3 个以上 package,直接建议拆 commit。
Monorepo 里 scope 写错的代价很高——发布工具通常靠它决定要不要发版、发哪个包。
③ Squash merge 场景(PR 标题即 commit)
这是 PR 的最终 squash message,读者是没看过 PR 讨论的人。
因此:body 必须能独立交代背景,不允许出现「如上」「见上文」「按讨论」这类指代词。
这一条最容易被忽略:PR 讨论里清清楚楚的上下文,squash 之后全部消失,只剩这条 message。
使用注意
- 大 diff 会截断或降质。单次改动超过几百行时,先按目录或功能模块拆 stage,再逐块生成。
- diff 里可能有密钥。把 staged diff 发给外部模型前,确认没有
.env、私钥、token;更稳的做法是先跑一遍密钥扫描。 - AI 不知道你没 stage 的东西。
git diff --cached只包含已 stage 的改动——这正是它比git diff更适合的原因:你 stage 了什么,message 就描述什么。 - 生成结果必须人读一遍再提交。commit message 是写给人看的,AI 负责把草稿写到 80 分,最后 20 分(尤其是 why)只能你来补。
什么时候用 / 别用
适合用:日常 1~3 个文件的改动(AI 最擅长把这类 diff 概括成一句话);重构与重命名这类「diff 很大但语义单一」的改动——人类写这种 message 最容易偷懒写成 refactor;已经 stage 好、改动范围明确的提交。
不适合用:
- 你还没想清楚这次改动为什么做。message 里最有价值的是 why,而 why 只有你知道。AI 能把 what 写到 80 分,why 只能你来补。
- 单次改动超过几百行。会截断或降质,先按目录或功能模块拆 stage 再逐块生成。
- diff 里含密钥或敏感配置。把 staged diff 发给外部模型前务必确认,更稳的做法是先跑一遍密钥扫描。
验收判据
- body 能独立交代背景——不允许出现「如上」「见上文」「按讨论」这类指代词。squash 之后 PR 讨论全部消失,只剩这条 message,这是最容易被忽略的一条。
- 标题能回答「改了什么」,body 能回答「为什么改」。只有前者的 message,三个月后等于没有。
- 用
git diff --cached而不是git diff——AI 不知道你没 stage 的东西,你 stage 了什么,message 就描述什么。 - 生成结果必须人读一遍再提交。AI 负责把草稿写到 80 分,最后 20 分只能你来补。
三种变体(可直接抄)
# A. 常规提交:只看 staged diff,输出一句话标题 + 背景
git diff --cached | claude -p "写一条 conventional commit,标题 ≤50 字符,body 说明 why"
# B. 拆分建议:让 AI 判断这次 staged 是否该拆成多次提交
git diff --cached | claude -p "判断这批改动是否应拆成多次提交;若应拆,给出按文件分组的方案"
# C. 批量补写:为最近 N 次提交重写 message(慎用于已推送的提交)
git log -5 --format=%H | while read h; do
git show --stat --format="" "$h" | claude -p "为这次改动写一条 conventional commit"
done
变体 C 会重写历史。只对尚未推送的本地提交使用;已推送的提交重写会破坏协作,除非整个团队已明确同意。
更新说明
- 2026-10-17:补充「什么时候用 / 别用」「验收判据」与三种可直接抄的变体。
延伸阅读
- PR Review 第一道筛 Prompt · Staff 级 Code Review Prompt — commit 之后的审查环节
- Claude Code 深度评测 — 跑上面 aicommit 自动化脚本的工具