目录
- 一、先定规则:AI 只写文案,不碰仓库动作
- 二、可复制 Prompt(按 staged diff 用)
- 三、Conventional Commits 速查(给 AI 也给你)
- 四、五个坑
- 坑 1:工作区全量当 staged
- 坑 2:一条 commit 揉进两件事
- 坑 3:复述 diff,不写动机
- 坑 4:type 选飘
- 坑 5:自动提交 / 自动 push
- 五、和 PR 描述怎么分工
- 六、什么时候不用 AI
- 小结
写 commit message 这件事,烦的不是「想不出来」,是改了一堆文件之后,已经懒得准确概括了。
于是两种极端很常见:要么随手来一句update/fix,半年后git blame等于没有;要么把 AI 生成的长文原样贴上去,subject 80 个字,body 里还在复述 diff 里一目了然的细节。
这篇讲我怎么让 AI 写 commit,以及五个真实踩过的坑。附可复制 Prompt 和 Conventional Commits 模板。
一、先定规则:AI 只写文案,不碰仓库动作
这是底线,建议写进个人习惯甚至团队约定:
| AI 可以做 | AI 不要做 |
|---|---|
| 根据staged diff起草 message | 自动git commit(除非你显式确认) |
| 按团队规范改写 subject/body | 自动git push |
| 把乱七八糟的草稿收成规范格式 | 擅自git add未审查文件 |
| 提醒「这次 staged 像是混了两件事」 | 改历史(rebase/amend)除非你要求 |
一句话:生成归生成,提交的按钮永远在人手里。
二、可复制 Prompt(按 staged diff 用)
把git diff --cached的结果贴进去(或让编辑器把 staged 变更喂给 AI):
根据下面的 staged diff,写一条 Git commit message。 规范: - 使用 Conventional Commits - subject:type(scope): 摘要;不超过 72 字符;祈使句;不加句号 - type 仅用:feat / fix / refactor / docs / test / chore / perf / ci - body 可选;有则说明「为什么」和「影响」,不要逐文件复述 diff - 中文或英文与团队现有 log 保持一致(本仓库用:____) 约束: - 只描述 staged 里真实存在的变更,禁止猜测未出现的动机 - 若 staged 明显包含两件无关的事,先指出,并给出「拆成两条」的建议,不要硬揉成一条 - 不要加入 Co-authored-by、emoji(除非我要求) - 输出两个候选,我来选 staged diff: <粘贴 git diff --cached>把「本仓库用」那一行改成中文或英文。候选给两条很有用:一条偏短、一条带 body,选起来快。
我在 wescode 里会直接对当前变更说「按 Conventional Commits 写 commit message,给两个候选」;逻辑和上面一样,关键是范围锁定在 staged,别让它根据整个工作区幻想。
三、Conventional Commits 速查(给 AI 也给你)
<type>(<scope>): <subject> [body] [footer]常用 type:
| type | 何时用 |
|---|---|
feat | 新功能 |
fix | 修 bug |
refactor | 行为不变的结构整理 |
docs | 只改文档 |
test | 只改测试 |
chore | 构建/工具/杂项 |
perf | 性能 |
ci | CI 配置 |
好的 subject 例子:
feat(auth): 支持 refresh token 轮转 fix(download): 修复断点续传校验和为空 refactor(store): 拆分 ListBuilds 查询逻辑差的 subject(AI 也常写出来):
update code fix bug 优化了一些东西 Update auth.go and handler.go四、五个坑
坑 1:工作区全量当 staged
未git add的文件、本地调试打印、半成品实验,AI 若看到整个工作区,会写进 message。结果是:message 描述了你没打算提交的东西,或反过来,真正 staged 的要点被稀释。
习惯:先git add -p(或按文件 add)→ 再生成。只喂git diff --cached。
坑 2:一条 commit 揉进两件事
改了登录,又顺手格式化了无关包。AI 常会写:
feat(auth): 登录支持 MFA 并统一代码风格看起来完整,回滚和 cherry-pick 会很痛。正确反应是:让 AI 指出混杂,然后拆 commit,而不是追求「一条说完」。
Prompt 里那句「两件无关的事先指出」就是为这个准备的。
坑 3:复述 diff,不写动机
AI 默认爱写:
- 修改了 a.go - 新增了 b.go - 删除了 c.go这是git show --stat就能看到的。body 该写的是:
- 为什么改(缺陷表现、需求背景)
- 有意不做的取舍(「暂不迁移旧接口」)
- 风险提示(「需跑迁移」「兼容旧客户端」)
生成后扫一眼:body 里如果全是文件名,删掉重写「为什么」。
坑 4:type 选飘
把「修文案」写成feat,把「真的新接口」写成chore,后面按 type 筛 changelog / 自动发版会乱。
简单校准:
- 用户可感知的能力变化 →
feat/fix - 只有开发者在意 →
refactor/test/chore - 拿不准时,看「用户会不会在发版说明里看到它」
坑 5:自动提交 / 自动 push
部分工具或脚本支持「生成并 commit」。省事的代价是:
- message 还没看就进历史了
- 误 add 的文件一起进去了
- 钩子(lint-staged、测试)失败时更难收拾
我的做法:永远先展示候选 → 人确认 → 再手动 commit。AI 加速的是措辞,不是跳过审查。
五、和 PR 描述怎么分工
| 产物 | 该写什么 |
|---|---|
| commit message | 这一小步「做了什么 + 为何」 |
| PR 描述 | 整单动机、测试计划、风险、截图/关联 issue |
别让 AI 把 PR 长文塞进每一条 commit;也别指望一条feat: ...能代替 PR。我的常用顺序:
- 本地多次小 commit(AI 助写 message)
- 开 PR 时再让 AI 根据
main...HEAD的 log + diff 写 PR 描述 - PR 描述里单独要「测试计划」和「风险」,commit 里不必重复
六、什么时候不用 AI
改动就一行、意图一眼能看清。自己敲fix(api): 纠正空指针更快。
message 需要写进合规/审计语境。涉及安全修复措辞、对外披露口径时,人定稿,AI 最多给草稿。
你还没 staged、自己都没理清改了什么。先整理 diff,再写 message;顺序反了,AI 只会帮你把混乱写得很流畅。
小结
用 AI 写 commit message,收益很大,但只在三个前提下:
- 输入是staged diff,不是整个乱七八糟的工作区
- 输出遵守团队规范,并且人确认后再 commit
- 发现「一条里两件事」时选择拆分,而不是硬概括
Subject 写动机与范围,body 写为什么;别让 AI 当你的git status复读机。
上面的 Prompt 和流程我是在日常提交里用的,编辑器侧用的是 wescode,官网是 weisyn.com。你们团队对 AI 写 commit 还有什么强制规范,欢迎评论区贴出来一起抄作业。