代码是工程师之间沟通的载体,而不只是给机器执行的指令。你编写提交信息、注释和组织合并请求的方式直接决定了团队能否顺畅读懂代码、排查故障并在此基础上进行迭代开发。
代码即沟通
工程师无时无刻不在沟通。Slack 消息、设计文档、RFC 讨论帖、代码评审批注 —— 这份工作既要攻克技术难题,同样重要的是向他人清晰传递开发意图。
但有一个沟通渠道却常常得不到同等重视:代码本身。所有与代码有关的东西都应当属于这个沟通渠道的一部分。
代码不只是给机器执行的指令,更是写给下一个需要阅读、扩展或调试它的工程师的消息。它是写给参与代码评审的团队成员的消息。它是写给六个月后的你自己的消息,那时候,你已经忘记了所有的原始上下文信息。一条提交信息就是一条必须独立存在的 Slack 消息,没有对话上下文,无法追问补充,通常是在它被写下数年后才会被阅读。
一旦你把代码视为沟通媒介,你需要问自己的问题就会改变:这条提交记录能否独立看懂?有人能否顺着逻辑评审这个合并请求吗?这段注释是在阐释代码的设计初衷,还是仅仅复述了代码本身的行为?
你的本地工作流是你自己的事。你可以反复尝试、重写、丢弃,杂乱的草稿是找到好想法的一个过程。但一旦代码准备合并,规则就变了。到那时,你产出的不仅仅是一段代码变更记录,而是代码库的组成部分。有人会依靠它弄清文件修改缘由、故障引入节点,以及这份合并请求意在解决何种问题。在那一刻,请沉下心问自己:这个变更能否清晰完整地向他人讲清前因后果?
一个 PR 就是一个故事
这里有一个实用的思考方式:把合并请求比作一本书,每一次代码提交就是一个章节,提交中的代码改动是正文。没人会随意跳页看书,人们都是按顺序阅读,故事之所以有意义,是因为作者精心安排了行文顺序。评审人员按提交顺序查看代码时应当能顺畅理清你的思路,无需凭空揣测,也不用一次性记住全部改动才能看懂其中的任意片段。
在实践中可能是这样的:
为接口新增搜索端点
实现基础相关性排序功能
将排序逻辑抽离为独立模块
编写排序单元测试
编写搜索接口集成测试
按顺序看完这五条提交记录,你就知道发生了什么:这个功能是逐步构建好的,排序逻辑被抽离为独立模块,同时完成了单元测试与集成测试。你不需要借助 PR 描述来复盘这个过程,提交本身就讲述了这一切。
想要实现这种效果,每一个提交都要具备独立的意义。一次重命名加一次行为改变不是一件事,这是两个独立的改变,通常应该分成两个独立的提交。这些“章节标题”和章节内容同等重要,提交说明本身需要自带必要的上下文信息。像修复 ABC-123 这样的消息只是指向了外部的上下文,日后他人查阅时,对应的外部上下文或许已经无法获取到。
简短、以动词开头的提交说明效果更好:
提取验证器
重构:在表单中使用验证器
修复:处理提交时的边界情况
按顺序阅读它们,你就知道了整个故事的脉络。
在进行评审时,切勿在沟通未结束时重写提交记录,而是添加新的提交。评审人员的评论会锚定到特定的行,如果你强制推送并重写提交历史,锚定关系会失效,沟通脉络将无从追溯。保留原始故事,在其基础上新增提交处理反馈,后续任何人都能准确看到这个 PR 是如何演变的。
另一端查看代码的人
编写代码时时刻兼顾沟通性,评审人员的体验会截然不同。他们不再需要从一堆零散的改动中费力揣摩开发意图,而是在跟随一个叙事。这样做会增加代码编写者的工作量,但能降低其他协作人员的沟通成本,尤其是那些未参与前期方案探索的评审人员。在团队协作场景中,这样的取舍是十分值得的。条理清晰的合并请求更便于评审,长期来看优势显著。不用花费大量时间推敲开发初衷,便能把更多精力聚焦于代码改动本身。
评审人员并非唯一的阅读者。数年后可能会有人回头查看这段代码,想知道某些代码行为为什么会存在。规范清晰的提交历史给了他们一条回溯上下文的路径:找到新增该代码的提交、对应的合并请求以及背后做出的权衡。如果没有这条追溯线索,人们很容易误改动原本有意设计的代码逻辑。
代码注释也是同理。代码本身已经展示了行为逻辑,但往往无法说明代码存在的原因、有哪些限制条件以及隐含的预设逻辑。像// 计数器自增这样的注释毫无意义,而// 必须在订阅创建前执行,否则回调会在状态就绪前触发则是关键的说明文档。这类注释能节省数小时的调试时间,从根源上规避潜在缺陷。
AI 生成代码让这一点变得更重要,而不是更不重要
AI 智能体可以快速生成大量代码,但效率无法替代开发背景信息。后期整理修复的成本远超多数团队预期的提速收益。 如果放任 AI 自主输出,最终只会生成一个巨大的提交,附带一条“实现功能”的提交信息,没有任何关于背后推理的痕迹。
让 AI 智能体遵循和人类工程师相同的规范就能改变这种情况。原子化提交能让 AI 的设计思路清晰可读:你能看清它先构建了什么、在哪里重构了代码、编写了哪些测试以及整体的实现顺序。这不仅有助于理解代码,还能在缺陷上线前提前发现 AI 逻辑中的疏漏。如果一条提交直接从“新增接口”跳到“新增集成测试”,中间缺少过渡步骤,这本身就是一个风险信号。条理清晰的提交记录具备可审计性,这是单一杂乱的代码变更无法实现的。
代码本身依然是信息,只是如今编写它的人未必是人类。
结构是信息的一部分
如果你仔细阅读就能发现,本文每个标题都能在阅读正文前提前告诉你当前章节要讲什么内容,无需通读全文就能清楚当前章节的主题。好的提交说明、结构清晰的合并请求也是同理。清晰的结构本身就是一种信息传递,如果做得好,读者就永远不需要去猜测其中的含义。





