Chesterton 的中指:13 年 295 行 commit message

Chesterton 的中指:13 年 295 行 commit message

工程实践Commit Message代码考古Chesterton栅栏

数据源:arp242.net + Lobsters discussion

Martin(arp242)最近接手了一个遗留项目。他做的第一件事——在真正读代码之前——是跑了一条命令:

git log --no-merges --format=format:'%b' | sed '/^$/d' | wc -l

结果是 295。13 年里,这个项目的所有提交说明加起来只有 295 行。去掉 dependabot 自动提交、「revert commit」和「fix typo」之后,剩下 167 行。平均每月一行。

没有文档。几乎没有注释。而前一个开发者的三周交接期,沟通质量和 commit log 处于同一水平。「我从未如此理解 Jack Bauer 用极端手段获取信息的心情,」Martin 写道,「后悔没试试。」

栅栏的两面

Chesterton 栅栏原则在软件工程里流传已久:你看到一段奇怪的代码,想删掉它,但应该先搞清楚它为什么在那里——它可能挡着某种你没意识到的危险。这是正面。G.K. Chesterton 的原话是,改革者在拆掉一道栅栏之前,必须能够回答「为什么它被建在这里」。

Martin 给出了它的背面——Chesterton 的中指。

「是的,我们做了所有这些奇怪的事,但我们不打算告诉任何人为什么。去你的。」

栅栏存在的意义依赖上下文。当上下文随 commit message、注释和文档一起消失后,栅栏就不再是保护,而是诅咒。后来的开发者面对的是一个没有铭牌的遗迹:一堆说不清道不明的破烂,要么花几个月考古,要么冒险拆掉。

三种毒 commit

Martin 没有系统性地分类,但他的描述勾勒出了三种最具破坏力的提交模式:

「fix page A」——空洞标题。 即使是大规模改动,提交标题也只有「fix page A」。标题不传达任何信息,正文为空。后来的开发者只能逐行 diff 反向推测意图——精确度约等于读骨占卜。

WIP commit——半成品搁浅。 未完成的重构散落在代码库里。旧功能的残骸没有被清理。已经添加但从未被链接、没有任何用户使用的功能静静地躺在代码深处。它们不是 bug,但比 bug 更棘手——bug 至少有人报。

「不需要」型——Chesterton 的 Gap。 Martin 引入了一个对称概念:如果 Chesterton 的栅栏是「建了墙但不告诉你为什么」,那 Chesterton 的 Gap 就是「没有墙的地方也要建一道」——在没人需要的地方添加抽象层、过度工程化、为一个不存在的未来需求预埋设计。

这三种模式共同构成了一个代码库的考古学灾难:后人不仅要理解代码在做什么,还要推断前人为什么这么做,以及他们当时打算怎么做。

三个问题

Martin 给出了一个接地气的 commit message 框架——三个问题:

  1. 你改了什么?
  2. 为什么改?
  3. 为什么这是好的解决方案?

「Implement new feature X」有时候够用,但大多数时候总有东西可以说——哪怕只是解释一个参数的选择、一个边界条件的来源、一个被否决的替代方案。

不需要优美的英文。不需要写成哲学论文。忘记写某个要点也可以接受(但写了更好)。底线是:有就行。 任何半认真的尝试都无限优于空白。

Martin 的判断很硬:「写 commit message 不是可选附加项。它是工作的一部分。不写就是不完成本职工作。」

Lobsters 社区的共识

Lobsters 上这篇文章获得了 106 分,评论区几乎没有争议。一位用户写道:「我花了五年时间在全球各地修复这类代码库。随身带着《Working Effectively with Legacy Code》睡觉。」

另一位用户 david_chisnall 的观点击中了 code review 的核心价值:「Code review 最大的好处是逼你把所有未说出口的上下文写下来。你自己解释不清的、reviewer 看不懂的,都得写进注释。」

还有一个被反复提及的场景:接手同事离职后的代码库。当你无法向任何人提问时,commit log 是最后的信息源。如果它是空的,你面对的不是代码——是考古现场,而所有铭文都被刻意抹掉了。

为什么这件事在今天尤其重要

AI 编码工具(Codex、Claude Code、Copilot)正在让代码生产速度提升一个数量级,但 commit message 不会自动生成——或者说,自动生成的「Add files via upload」「Update code」比空白更糟糕,因为它们制造了一种「有文档」的假象。

一个 13 年只有 295 行 commit message 的项目,在 AI 辅助编程的时代只会更常见,不会更罕见。因为生产代码比写注释快,而 AI 目前还不会替你觉得「这里应该解释一下为什么选这个数据结构而不是那个」。

Martin 最后写道:「如果你什么都不写,你就是在对每一个后来人竖中指。」这个比喻粗鲁,但准确。Commit message 不是写给自己的备忘录——它写给三年后的你,写给接手你工作的同事,写给半夜被 on-call 拉起来排查 regression 的那个人。

本文的素材来自公开信息和社区讨论。如果你对这个话题有更深入的一手经验,欢迎指出文中的不足。