# 编写良好的 CL 描述

CL 描述是一项公开的记录，其内容包含修改了 **什么** 与 **为什么** 这么修改。 虽然你的 CL 只是在你与审核者之间发生，但它是版本控制历史的一部分，若干年之后，很有可能会有成百上千的人阅读。

以后的开发者可能会根据描述搜到你以前写的 CL 。在没有精确数据的情况下，他可能根据自己的模糊记忆搜索 CL。如果所有的信息都只包含在代码里面，描述中几乎没有相关内容，那么定位到你的 CL 将会花费太多的时间。

## 第一行 <a href="#first-line" id="first-line"></a>

* 简短描述做了什么。
* 完整的句子，祈使句。
* 后面空一行。

CL 描述的 **第一行** 应该是一句简短的描述，用以说明 *CL做了* **什么** 。在第一行后面留一空行。以后有开发者搜索版本控制历史的代码时，这是他们看到的第一行，所以第一行应该提供足够的信息，他们不必阅读代码，也不必阅读整个描述，只需扫一眼便知道 CL 做什么，或者知道这条 CL 与其他 CL 的区别在哪里。 也就是说，第一行应该是独立的，以便阅读代码的人快速的了解代码的功能或作用。

尽量保证第一行简短、重点突出、切中要害。对读者而言，清晰度和实用性是最重要的。

一般而言，CL 描述的第一行是以命令口吻（祈使句）写的一句话。举例说明，我们应该写“ **删除** FizzBuzz RPC，并用写的系统 **替换** 它。”，而不是写成 “ **删除了** FizzBuzz RPC，并 **已经** 用写的系统 **替换** 它。” 当然，第一行写成祈使句就可以了，其他内容不必如此。 (译者注：原文中的反面例子是现在进行时。但在中文中现在进行时与祈使句基本一致，不好翻译。此处改成了现在完成时。)

## 描述内容要提供充分的信息 <a href="#informative" id="informative"></a>

第一行应该是简短、重点突出的摘要，而描述的其他部分应包含详细信息，包括阅读代码的人全面理解修改内容所需的任何补充信息。它可能包括对正在解决的问题的简要描述，以及为什么这是最好的方法。如果该方法有任何缺点，应该指出来。如果有相关背景信息的，如 bug 编号、基准结果和设计文档的链接。

如果包含的链接是外部资源，请考虑访问限制或保留策略，未来的读者可能看不到这些链接。在描述中尽可能包含足够的上下文，以便审核者和未来的读者理解 CL。

即使是小的 CL，也应该包含这些信息。

## 糟糕的 CL 描述 <a href="#bad" id="bad"></a>

“修复 bug”是一个很不恰当的描述。哪个 bug ？你做了哪些事情来修复它？通通都没有。类似糟糕的描述还包括：

* “修复编译。”
* “增加补丁。”
* “把代码从 A 移到 B。”
* “第一阶段。”
* “增加方便的功能。”
* “清除死链。”

以上这些都是我们在真实案例中见过的 CL 描述。作者可能认为他们提供了足够的信息，其实它们不符合 CL 的目的描述。

## 良好的 CL 描述 <a href="#good" id="good"></a>

这是几个良好描述的样例。

### 功能修改 <a href="#function_change" id="function_change"></a>

> RPC：移除 RPC 服务器的消息空闲列表的大小限制。
>
> 服务器（如 FizzBuzz）有大量的消息，可以从重用中受益。使空闲列表更大，并添加一个goroutine，随着时间的推移缓慢释放空闲列表，以便空闲 服务器最终释放所有空闲列表。

前面几句话描述了 CL 做什么的，接下来描述解决了什么问题，为什么这是一个好的解决方案，最后涉及到了一些实现细节。

### 重构 <a href="#refactoring" id="refactoring"></a>

> 构建一个带 TimeKeeper 的 Task，以便使用它的 TimeStr 和 Now 方法。
>
> 在 Task 中增加一个 Now 方法，然后删掉 borglet() 方法（这个方法仅仅被 OOMCandidate 使用，它调用了 borglet 的 Now 方法）。这样就替换掉 Borglet的方法，把它委托给 TimeKeeper。
>
> 让 Tasks 提供 Now 是减少对 Borglet 的依赖所做的一小步。最终，从 Task 上调用 Now 的方式会替代成直接调用 TimeKeeper，我们会逐步实现。
>
> 继续重构 Borglet 层次的长期目标。

第一行描述了 CL 做什么的，以及过去它是怎么改变的。描述的其他部分谈到了具体实现、CL 的上下文，这种方法并不完美，但在朝着完美的方向前进。而且也解释了 *为什么* 应该这么改。

### 需要一些上下文的小 CL <a href="#small_cl_context" id="small_cl_context"></a>

> 为 status.py 创建一个 Python3 的编译。
>
> 在原始的编译（Python2）旁创建一个 Python3 的编译，让已经使用过 Python3 编译的用户根据某些规则选择 Python3 还是 Python2，而不是依赖于某个路径。 它鼓励新用户尽可能使用 Python3 而不是 Python2，并大大简化了当前正在使用的某些自动编译文件重构工具。

第一句话描述做了什么，其他部分解释 *为什么* 要这么修改，并向审核者提供了不少额外的上下文信息。

### 使用标签 <a href="#tags" id="tags"></a>

标签是手动输入的，目的是便于对 CL 进行分类。 工具可能支持标签，或者根据团队习惯使用标签。

例如：

* "\[tag]"
* "\[a longer tag]"
* "#tag"
* "tag:"

使用标签是可选的。

当添加标签时，考虑是否要把标签添加到 [CL 描述内容](#informative)中，或[第一行](#first-line)中，以便把它与内容区分开来。

以下是有标签和没有标签的例子：

```{.good}
好的标签样例

// 第一行中的标签保持简短。
[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
```

```{.bad}
不好的标签样例

// 在第一行中包含太多标签（或标签太长）。
//
// 对于这种情况，可以考虑把标签移到描述内容中，或把它修改得更简短。
// 
[banana peeler factory factory][apple picking service] Assemble a fruit basket.
```

### 自动生成的 CL 描述 <a href="#generated_cl_descriptions" id="generated_cl_descriptions"></a>

有些 CL 是有工具自动生成的。如果可能的话，它们的描述也应遵循此处的建议。也就是说，它的第一行应该简短、重点突出、独立的，并且 CL 描述正文应该包含信息丰富的细节，以帮助审核者和未来的代码搜索者了解每个 CL 的功能或作用。

## 提交 CL 之前审核描述 <a href="#review_before_submit" id="review_before_submit"></a>

在审核过程中，CL 可能会发生重大改变（与最初提交审核的 CL 相比）。在提交 CL 之前有必要再审视一遍 CL 描述，确保描述能够正确地反映 CL 做了什么。

下一章: [小 CL](/google/developer/small-cls.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://zijinshi.gitbook.io/google/developer/cl-descriptions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
