编写良好的 CL 描述
目录
CL 描述是一项公开的记录,其内容包含修改了 什么 与 为什么 这么修改。 虽然你的 CL 只是在你与审核者之间发生,但它是版本控制历史的一部分,若干年之后,很有可能会有成百上千的人阅读。
以后的开发者可能会根据描述搜到你以前写的 CL 。在没有精确数据的情况下,他可能根据自己的模糊记忆搜索 CL。如果所有的信息都只包含在代码里面,描述中几乎没有相关内容,那么定位到你的 CL 将会花费太多的时间。
第一行
- 简短描述做了什么。
- 完整的句子,祈使句。
- 后面空一行。
CL 描述的 第一行 应该是一句简短的描述,用以说明 CL做了 什么 。在第一行后面留一空行。以后有开发者搜索版本控制历史的代码时,这是他们看到的第一行,所以第一行应该提供足够的信息,他们不必阅读代码,也不必阅读整个描述,只需扫一眼便知道 CL 做什么,他们节省时间。
一般而言,CL 描述的第一行是以命令口吻(祈使句)写的一句话。举例说明,我们应该写“ 删除 FizzBuzz RPC,并用写的系统 替换 它。”,而不是写成 “ 删除了 FizzBuzz RPC,并 已经 用写的系统 替换 它。” 当然,第一行写成祈使句就可以了,其他内容不必如此。 (译者注:原文中的反面例子是现在进行时。但在中文中现在进行时与祈使句基本一致,不好翻译。此处改成了现在完成时。)
描述内容要提供充分的信息
描述内容应该提供足够的信息。它可能包含一段关于问题的简短描述,为什么这是最好的解决方案。如果有更好的解决方案,也应该提及。如果有的话,相关的背景信息,如 bug 编号、基准结果和相关的设计文档也应包含在内。
即使是小的 CL,也应该包含这些信息。
糟糕的 CL 描述
“修复 bug”是一个很不恰当的描述。哪个 bug ?你做了哪些事情来修复它?通通都没有。类似糟糕的描述还包括:
- “修复编译。”
- “增加补丁。”
- “把代码从 A 移到 B。”
- “第一阶段。”
- “增加方便的功能。”
- “清除死链。”
以上这些都是我们在真实案例中见过的 CL 描述。作者可能认为他们提供了足够的信息,其实它们不符合 CL 的目的描述。
良好的 CL 描述
这是几个良好描述的样例。
功能修改
RPC:移除 RPC 服务器的消息空闲列表的大小限制。
服务器(如 FizzBuzz)有大量的消息,可以从重用中受益。使空闲列表更大,并添加一个goroutine,随着时间的推移缓慢释放空闲列表,以便空闲 服务器最终释放所有空闲列表。
前面几句话描述了 CL 做什么的,接下来描述解决了什么问题,为什么这是一个好的解决方案,最后涉及到了一些实现细节。
重构
构建一个带 TimeKeeper 的 Task,以便使用它的 TimeStr 和 Now 方法。
在 Task 中增加一个 Now 方法,然后删掉 borglet() 方法(这个方法仅仅被 OOMCandidate 使用,它调用了 borglet 的 Now 方法)。这样就替换掉 Borglet的方法,把它委托给 TimeKeeper。
让 Tasks 提供 Now 是减少对 Borglet 的依赖所做的一小步。最终,从 Task 上调用 Now 的方式会替代成直接调用 TimeKeeper,我们会逐步实现。
继续重构 Borglet 层次的长期目标。
第一行描述了 CL 做什么的,以及过去它是怎么改变的。描述的其他部分谈到了具体实现、CL 的上下文,这种方法并不完美,但在朝着完美的方向前进。而且也解释了 为什么 应该这么改。
需要一些上下文的小 CL
为 status.py 创建一个 Python3 的编译。
在原始的编译(Python2)旁创建一个 Python3 的编译,让已经使用过 Python3 编译的用户根据某些规则选择 Python3 还是 Python2,而不是依赖于某个路径。 它鼓励新用户尽可能使用 Python3 而不是 Python2,并大大简化了当前正在使用的某些自动编译文件重构工具。
第一句话描述做了什么,其他部分解释 为什么 要这么修改,并向审核者提供了不少额外的上下文信息。
使用标签
标签是手动输入的,目的是便于对 CL 进行分类。 工具可能支持标签,或者根据团队习惯使用标签。
例如:
- “[tag]”
- “[a longer tag]”
- “#tag”
- “tag:”
使用标签是可选的。
当添加标签时,考虑是否要把标签添加到 CL 描述内容中,或第一行中,以便把它与内容区分开来。
以下是有标签和没有标签的例子:
好的标签样例
// 第一行中的标签保持简短。
[banana] Peel the banana before eating.
// 标签可以内嵌在内容中。
Peel the #banana before eating.
// 标签是可选的。
Peel the banana before eating.
// 如果能保证简短,多个标签也是可接受的。
#banana #apple: Assemble a fruit basket.
// 标签可以放在 CL 描述中的任何位置。
> Assemble a fruit basket.
>
> #banana #apple
不好的标签样例
// 在第一行中包含太多标签(或标签太长)。
//
// 对于这种情况,可以考虑把标签移到描述内容中,或把它修改得更简短。
//
[banana peeler factory factory][apple picking service] Assemble a fruit basket.
自动生成的 CL 描述
有些 CL 是有工具自动生成的。如果可能的话,它们的描述也应遵循此处的建议。也就是说,它的第一行应该简短、重点突出、独立的,并且 CL 描述正文应该包含信息丰富的细节,以帮助审核者和未来的代码搜索者了解每个 CL 的功能或作用。
提交 CL 之前审核描述
在审核过程中,CL 可能会发生重大改变(与最初提交审核的 CL 相比)。在提交 CL 之前有必要再审视一遍 CL 描述,确保描述能够正确地反映 CL 做了什么。
下一章: 小 CL