2219 字
约 7 分钟
18
S24-A25 · 提交信息:AI 写得比人整齐,但"为什么改"还是缺的

一个团队把"写 commit message"交给助手:给它 diff,让它生成规范格式。上线后提交记录"整齐了"——标题都是 feat: ...、正文都有三行要点。而半年后有人查"这个改动为什么改",发现"每条都在描述'改了什么'",没有一条说'为什么'。

提交信息有两个用途:事后检索"改了什么"(diff 也能回答)与事后理解"为什么这么改"(只有人能回答)。而 AI 从 diff 里能读出的,恰好只有前者。

1. 提交信息的三段价值

段 谁最清楚
改了什么(what) diff / AI
为什么改(why) 作者
有什么代价(tradeoff) 作者

第二与第三项是"AI 无法从 diff 推导"的:"因为线上 P99 超预算"这件事不在代码里——这个"半年后"的视角很有用:"改了什么"由 diff 永久保存,而"为什么"只存在"提交信息"里——一旦没写,它就永久丢失了(除非去翻 PR 或聊天记录)。
而它恰恰是"半年后最想知道"的信息。

2. "AI 生成"的三种常见形态

形态 问题
只写标题 缺 why
标题 + 要点(复述 diff) 内容冗余,仍缺 why
标题 + 要点 + 作者补一句 why 可用

第三项是"人机分工"的正解:AI 负责"结构化",人负责"那句 why"第三项的"成本"极低:"结构"由 AI 补(几十秒),"一句 why"由人补(十秒)——而"十秒"是"愿不愿意"的分界;要人写"三段分析",多数人就不会写。
——而"一句"很容易写,于是它真的会被写。

"why"能不能"事后补",有一个简单判据:

// 三种"为什么"的可补性
1 因为"线上指标"(P99/错误率)→ 日志里能查到,可补
2 因为"业务决策"(客户要求/合规)→ 只在人脑/工单里,难补
3 因为"踩过的坑"(某库的 bug)→ 有 issue 链接就够,无则丢失
// 判据:第 2 类必须"当场写",因为它"无法回溯"

3. "why 一行"该怎么写

写法 效果
"修复 bug" 无信息
"修复 502(上游超时未设)" 有信息(原因)
"修复 502:上游超时缺失,长尾请求被挂住 30s" 最好(现象 + 原因)

第三项的"作用"在"评审"上:"不修的后果"让评审者"知道该不该现在改"——而"没有它"时,评审只能"看代码猜严重性"。
第三项的结构是"改了什么 + 因为什么 + 不修的后果"——而"不修的后果"是"评审与回溯"最需要的。

// 一条"够用"的提交信息(四段)
fix: 给上游调用加 3s 超时
(why)线上 P99 出现 30s 挂起,根因是 socketTimeout 未设(默认无限)
(what)WebClient 加 responseTimeout + 连接超时,整体 6s
(note)重试 2 次、退避 200ms,整体超时包在 retryWhen 外

"AI 生成 + 人工补 why"可以用"一个钩子"落地,成本不高:

// pre-commit 或 prepare-commit-msg 里:检测"有无 why 段"
if ! grep -qE '^(why|因为|原因)[::]' "$1"; then
  echo "提交信息缺少 why 段:请补一行'因为……'" >&2
  exit 1
fi
// 判据:没有 why 就不让提交(比"评审时提醒"有效得多)

4. "格式规范"的三种取舍

取舍 适合
严格 Conventional Commits 有"自动 changelog"需求
只需"标题 + why" 多数团队(够用)
自由格式 单人/短期

第二项是"性价比最高"的:它不要求"类型前缀",只要求"一句 why"第二项的"理由"是"检索成本":git log --grep="why" 找不到东西,而"人读历史"时**"标题 + 一句 why"已经够用**。
——而"类型前缀"对"检索历史"帮助有限(grep fix: 也能代替)。

5. "AI 生成提交信息"的三个前提

前提 说明
diff 必须"完整"(含新增文件) 否则漏改
提交粒度要"一件事" 否则标题只能笼统
作者要"补 why" 否则只有 what

第二项的"因果"值得强调:"笼统"不是"生成器不行",而是"输入就是五件事"——修法是"拆提交",不是"换个更好的生成器"。
第二项是"根问题":"一次提交改了五件事"时,任何生成器都只能给出"若干改动"——而"笼统"的根因在"提交粒度",不在"生成器"。

"提交粒度"这条可以量化,而不是靠"感觉":

// 三个数(按周看)
1 平均每提交改动文件数:> 5 通常"混了多件事"
2 提交信息的"类型分布":全是 fix → 可能"攒着一起提交"
3 单次提交的行数:> 400 行 → 评审与回溯都困难
// 判据:1 与 3 高、2 单一时,先"拆提交",再谈"格式规范"

6. 排错:五种"提交信息问题"

现象 成因 处理方向
全是"改了什么" 无 why 段 模板加一行
提交信息与 diff 不符 diff 不完整 检查生成输入
标题笼统("若干修复") 提交粒度太大 拆提交
历史里找不到"为什么" 从不写 why 加"必填一行"
规范很重但没人看 形式大于内容 简化格式

"PR 描述承载 why"是个常见折中,而它有个"依赖":

// 三种"why 在哪里"的分工
1 提交信息里(最不易丢,随代码走)
2 PR 描述里(易丢:换平台/清理时没了)
3 工单系统里(需"链接 + 可访问")
// 判据:三年后"clone 代码"还能不能看到 why —— 只有 1 能

7. 边界:什么情况"只写标题"就够

场景 为什么 做法
格式化/重命名(无语义变化) why 等于 what 只写标题
依赖升级(版本号自明) 版本即信息 只写标题
一次性脚本/临时分支 不进主干 随意
已由 PR 描述承载 why 有单一来源 标题 + 链接 PR

判断口径一句话:"半年后,别人只读这条消息,能不能知道"为什么改"。最后一条与"规范"有关的边界:"模板"要"短":标题必填、why 必填、其余可选——一旦模板有五个必填项,"填模板"就成了"写作文",于是大家开始"糊弄"。
能(格式化、版本升级),标题够;不能(修 bug、改行为、加约束),必须"一句 why"——而"一句"正是 AI 写不出、人写起来最便宜的东西。

再补一个"团队"现实:提交信息是"写给未来的自己"的——而"未来的自己"最缺的不是"改了什么"(git 能算),而是"当时在权衡什么"。所以"why 一行"的价值随"时间"增长:今天写它花十秒,一年后省半小时,三年后可能省一次"事故复盘"。这个投入产出比,在工程实践里几乎是最高的之一,而它的门槛低到"只要愿意写一句"。

而"AI 生成"真正的价值,是把"写一句 why"的门槛从"格式要求"降到"填空":它给好骨架,你只补一处——于是"规范"第一次变得"可持续"。

最后一个"反例"值得记:有些团队的提交信息"非常规范"(类型、范围、破坏性变更都齐),而"为什么改"依然无从查找——因为规范只约束"形式",不约束"信息"。所以"加一行 why 必填"这种"小约束",比"全套 Conventional Commits"更能提升历史质量;而它的迁移成本也最低:只改模板,不改工具链。

而"只改模板"这件事,一小时内就能做完。

8. 自测

  1. 提交信息的三段价值里,哪两段"AI 无法从 diff 推导"?为什么?
  2. "标题 + 要点(复述 diff)"为什么"内容冗余仍缺 why"?
  3. "why 一行"最好写成什么结构?"不修的后果"为什么重要?
  4. 为什么"严格 Conventional Commits"未必划算?
  5. "提交粒度"为什么是"标题笼统"的根因?
  6. 判断"只写标题是否够"的那个问题是什么?
S24-A25 · 提交信息:AI 写得比人整齐,但"为什么改"还是缺的
https://www.clxhxhhr.top/posts/6675/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。