Skip to content

Add simplified Chinese translation #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions zh-cn/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# 谷歌工程实践文档

Google 有许多通用工程实践,几乎涵盖所有语言和项目。此文档为长期积累的最佳实践,是集体经验的结晶。我们尽可能地将其公之于众,您的组织和开源项目也会从中受益。

当前包含以下文档:

* [Google 代码审查指南](review/index.md),其中包括以下两套指南:
* [代码审查者指南](review/reviewer/index.md)
* [代码开发者指南](review/developer/index.md)

## 术语

文档中使用了 Google 内部术语,在此为外部读者澄清:

* **CL**: 是 changelist 的缩写,代表一份已经提交到版本控制或正在进行代码审查的一段独立式更改。在其他组织内可能又会将其称为"变更 (change)或"补丁 (patch)"。
* **LGTM**: 是 Looks Good to Me 的缩写,意谓着 "我觉得很棒"。当代码审批者说了这句话就代表你的更改被批准了。

## License

本项目中的文档适用于 CC-By 3.0 许可证,该许可证鼓励您共享这些文档。有关详细信息,请参阅 <https://creativecommons.org/licenses/by/3.0/>。

<a rel="license" href="https://creativecommons.org/licenses/by/3.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by/3.0/88x31.png" /></a>
85 changes: 85 additions & 0 deletions zh-cn/review/developer/cl-descriptions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# 写好 CL 描述

CL 描述是进行了**哪些更改**以及**为何更改**的公开记录。CL 将作为版本控制系统中的永久记录,可能会在长时期内被除审查者之外的数百人阅读。

开发者将来会根据描述搜索您的 CL。有人可能会仅凭有关联性的微弱印象,但没有更多具体细节的情况下,来查找你的改动。。如果所有重要信息都在代码而不是描述中,那么会让他们更加难以找到你的 CL 。

## 首行 {#firstline}

* 正在做什么的简短摘要。
* 完整的句子,使用祈使句。
* 后面跟一个空行。

CL 描述的**第一行**应该是关于这个 CL 是**做什么**的简短摘要,后面跟一个空白行。

这会是版本控制历史记录摘要中显示的内容,因此第一行应该提供足够的信息,以便将来的代码搜索者不必阅读您的 CL或其全部描述即可了解您的 CL 的**实际功能**或与其他 CL 的区别。也就是说,第一行应该独立存在,从而使读者可以更快地浏览代码历史记录。

尝试让第一行保持简短,专注且切题的。清晰度和实用性对于读者而言应该是最重要的事。

按照传统,CL 描述的第一行应该是一个完整的句子,就好像是一个命令(一个命令句)。例如,“**Delete** the FizzBuzz RPC and **replace** it with the new system.”而不是“**Deleting** the FizzBuzz RPC and **replacing** it with the new system.“ 但是,您不必把其余的描述写成祈使句。

## Body 是信息丰富的 {#informative}

其余描述应该是提供信息的。可以包括对正在解决的问题的简要描述,以及为什么这是最好的方法。如果这个方法有任何缺点,应该提到它们。如果有其他相关信息,请将有关的背景信息例如 bug numbers, 测试结果,设计文档的链接写在 CL 描述里面.

如果你的描述里有指向外部资源的链接,请考虑到这些链接有可能有时效性和访问限制,有些读者可能打不开这些链接。因此请尽可能可能包含足够的上下文,以供审阅者和将来的读者理解你的 CL。

即使是小型 CL 也需要注意细节。在 CL 描述中提供上下文以供参照。

## 糟糕的 CL 描述 {#bad}

“Fix bug ”是一个不充分的 CL 描述。什么 bug?你做了什么修复?其他类似的不良描述包括:

- "Fix build."
- "Add patch."
- "Moving code from A to B."
- "Phase 1."
- "Add convenience functions."
- "kill weird URLs."

其中一些是真正的 CL 描述。儘管简短,却并没有提供足够有用的信息。

## 好的 CL 描述 {#good}

以下是一些很好的描述示例。

### 功能更新

示例:
> rpc:删除 RPC 服务器消息 freelist 上的大小限制。
>
> 像 FIzzBuzz 这样的服务器有非常大的消息,并且可以从重用中受益。增大 freelist,添加一个 goroutine,缓慢释放 freelist 条目,以便空闲服务器最终释放所有 freelist 条目。

前几个词描述了CL实际上做了什么。其余的描述讨论了正在解决的问题,为什么这是一个很好的解决方案,以及有关具体实现的更多信息。

### 重构

示例:
> Construct a Task with a TimeKeeper to use its TimeStr and Now methods.
>
> Add a Now method to Task, so the borglet() getter method can be removed (which was only used by OOMCandidate to call borglet's Now method). This replaces the methods on Borglet that delegate to a TimeKeeper.
>
> Allowing Tasks to supply Now is a step toward eliminating the dependency on Borglet. Eventually, collaborators that depend on getting Now from the Task should be changed to use a TimeKeeper directly, but this has been an accommodation to refactoring in small steps.
>
> Continuing the long-range goal of refactoring the Borglet Hierarchy.

第一行描述了 CL 的作用以及改变。其余的描述讨论了具体的实现,CL 的背景,解决方案并不理想,以及未来的可能方向。它还解释了为什么正在进行此更改。

### 需要上下文的小 CL

示例:
> Create a Python3 build rule for status.py.
>
> This allows consumers who are already using this as in Python3 to depend on a rule that is next to the original status build rule instead of somewhere in their own tree. It encourages new consumers to use Python3 if they can, instead of Python2, and significantly simplifies some automated build file refactoring tools being worked on currently.

第一句话描述实际做了什么。其余的描述解释了为什么正在进行更改并为审查者提供了大量背景信息。

## 自动生成的 CL 描述

部分 CL 是由工具生成。有可能的话,它们的描述也应遵循此处的建议。也就是说,他们的第一行应该简短,专注且切题的,独立存在,并且 CL 描述正文应包括足够充足详细信息,以帮助审阅者和将来的代码搜索者了解每个 CL 的作用。

## 在提交 CL 前审查描述

CL 在审查期间可能会发生重大变更。在提交 CL 之前检查 CL 描述是必要的,以确保描述仍然反映了 CL 的作用。

下一篇:[小型 CL](small-cls.md)
31 changes: 31 additions & 0 deletions zh-cn/review/developer/handling-comments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# 如何处理审查者的评论

当您发送 CL 进行审查时,您的审查者可能会对您的 CL 发表一些评论。以下是处理审查者评论的一些有用信息。

## 不是针对您 {#personal}

审查的目标是保持代码库和产品的质量。当审查者对您的代码提出批评时,请将其视为在帮助您、代码库和 Google,而不是对您或您的能力的个人攻击。

有时,审查者会对你写的代码感到不满意, 并在评论中表达了他们的不满。对于审查者来说,这不是一个好习惯,但作为开发人员,您应该为此做好准备。问问自己,“审查者试图与我沟通的建设性意见是什么?”然后像他们实际说的那样操作。

**永远不要愤怒地回应代码审查评论。**这严重违反了专业礼仪且将永远存在于代码审查工具中。如果您太生气或恼火而无法好好的回应,那么请离开电脑一段时间,或者做一些别的事情,直到您感到平静,可以礼貌地回答。

一般来说,如果审查者没有以建设性和礼貌的方式提供反馈,请亲自向他们解释。如果您无法亲自或通过视频通话与他们交谈,请向他们发送私人电子邮件。以友善的方式向他们解释您不喜欢的东西以及您希望他们以怎样不同的方式来做些什么。如果他们也以非建设性的方式回复此私人讨论,或者没有预期的效果,那么请酌情上报给您的经理。

## 修复代码 {#code}

如果审查者说他们不了解您的代码中的某些内容,那么您的第一反应应该是澄清代码本身。 如果无法澄清代码,请添加代码注释,以解释代码存在的原因。 只有当你觉得用代码注释也很难解释清楚的时候,再用 code review tool 的评论功能对你自己的代码做进一步的解释。

这样做是因为, 如果审查者不理解您的某些代码,那么代码的未来读者可能也不会理解。在 code review tool 中的评论对未来对这些读者没有什么帮助 (因大多数情况读者可能都只看代码而不是看 code review 里的评论),但澄清代码或添加代码注释确可以实实在在得帮助他们。

## 自我反思 {#think}

编写 CL 可能需要做很多工作。在终于发送一个 CL 用于审查后,我们通常会感到满足的,认为它已经完成,并且非常确定不需要进一步的工作。这通常是令人满意的。因此,当审查者回复对可以改进的事情的评论时,很容易本能地认为评论是错误的,审查者正在不必要地阻止您,或者他们应该让您提交 CL。但是,**无论您目前多么确定**,请花一点时间退一步,考虑审查者是否提供有助于对代码库和对 Google 的有价值的反馈。您首先应该想到的应该是,“审查者是否正确?”

如果您无法回答这个问题,那么审查者可能需要澄清他们的意见。

如果您已经考虑过并且仍然认为自己是正确的,请随时回答一下为什么您的方法对代码库、用户和/或 Google 更好。通常,审查者实际上是在提供建议,他们希望您自己思考什么是最好的。您可能实际上对审阅者不知道的用户、代码库或 CL 有所了解。所以提供并告诉他们更多的上下文。通常,您可以根据技术事实在自己和审查者之间达成一些共识。

## 解决冲突 {#conflicts}

解决冲突的第一步应该是尝试与审查者达成共识。 如果您无法达成共识,请参阅“[代码审查标准](../reviewer/standard.md)”,该标准提供了在这种情况下遵循的原则。
11 changes: 11 additions & 0 deletions zh-cn/review/developer/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# CL 开发者指南

本节页面的内容为开发人员进行代码审查的最佳实践。这些指南可帮助您更快地完成审核并获得更高质量的结果。您不必全部阅读它们,但它们适用于每个 Google 开发人员,并且许阅读全文通常会很有帮助。

- [写好 CL 描述](cl-descriptions.md)
- [小型 CL](small-cls.md)
- 当 CL 指派给多个审查者时,用 WANT_LGTM 去表明期望得到 LGTM。你可以利用 WANT_LGTM=any (预设行为) 或 WANT_LGTM=all 去表明。
- [如何处理审查者的评论](handling-comments.md)

另请参阅[如何执行代码审查](../reviewer/),它为代码审阅者提供了详细的指导。

74 changes: 74 additions & 0 deletions zh-cn/review/developer/small-cls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# 小型 CL

## 为什么提交小型 CL? {#why}

小且简单的 CL 是指:

- **审查更快。**审查者更容易抽多次五分钟时间来审查小型 CL,而不是留出 30 分钟来审查一个大型 CL。
- **审查得更彻底。**如果是大的变更,审查者和提交者往往会因为大量细节的讨论翻来覆去而感到沮丧——有时甚至到了重要点被遗漏或丢失的程度。
- **不太可能引入错误。** 由于您进行的变更较少,您和您的审查者可以更轻松有效地推断 CL 的影响,并查看是否已引入错误。
- **如果被拒绝,减少浪费的工作。** 如果您写了一个巨大的 CL,您的评论者说整个 CL 的方向都错误了,你就浪费了很多精力和时间。
- **更容易合并。** 处理大型 CL 需要很长时间,在合并时会出现很多冲突,并且必须经常合并。
- **更容易设计好。** 打磨一个小变更的设计和代码健康状况比完善一个大变更的所有细节要容易得多。
- **减少对审查的阻碍。** 发送整体变更的自包含部分可让您在等待当前 CL 审核时继续编码。
- **更简单的回滚。** 大型 CL 更有可能触及在初始 CL 提交和回滚 CL 之间更新的文件,从而使回滚变得复杂(中间的 CL 也可能需要回滚)。

请注意,**审查者可以仅凭 CL 过大而自行决定完全拒绝您的变更。**通常他们会感谢您的贡献,但要求您以某种方式将其 CL 改成一系列较小的变更。一方面,将大 CL 分离成多个小 CL 是很麻烦的,另一方面,去说服审查者直接接受你的大CL也会很花时间。 所以从一开始就写小 CL 会让整个过程简单很多。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

“在您编写完变更后,或者需要花费大量时间来讨论为什么审查者应该接受您的大变更,这可能需要做很多工作。首先编写小型 CL 更容易。”
->
"一方面,将大CL分离成多个小CL是很麻烦的,另一方面,去说服审查者直接接受你的大CL也会很花时间。 所以从一开始就写小CL会让整个过程简单很多。"

## 什么是小型 CL? {#what_is_small}

一般来说,CL 的正确大小是**自包含的变更**。这意味着:

- CL 进行了一项最小的变更,**只解决了一件事**。通常只是功能的一部分,而不是一个完整的功能。一般来说,因为编写过小的 CL 而犯错也比过大的 CL 犯错要好。写之前,您可以和您的审查者一起讨论一下怎样大小的 CL 最合适。
- 审查者需要了解的关于 CL 的所有内容(除了未来的开发)都在 CL 的描述、现有的代码库或已经审查过的 CL 中。
- 对其用户和开发者来说,在签入 CL 后系统能继续良好的工作。
- CL 不会过小以致于其含义难以理解。如果您添加新 API,则应在同一 CL 中包含 API 的用法,以便审查者可以更好地了解 API 的使用方式。这也可以防止签入未使用的 API。

关于多大算“太大”没有严格的规则。对于 CL 来说,100 行通常是合理的大小,1000 行通常太大,但这取决于您的审查者的判断。变更中包含的文件数也会影响其“大小”。一个文件中的 200 行变更可能没问题,但是分布在 50 个文件中通常会太大。

请记住,尽管从开始编写代码开始就您就已经密切参与了代码,但审查者通常不清楚背景信息。对您来说,看起来像是一个可接受的大小的 CL 对您的审查者来说可能是压倒性的。如有疑问,请编写比您认为需要编写的要小的 CL。审查者很少抱怨收到过小的 CL 提交。

## 什么时候大 CL 是可以的? {#large_okay}

在某些情况下,大变更也是可以接受的:

- 您通常可以将整个文件的删除视为一行变更,因为审核人员不需要很长时间审核。
- 有时一个大的 CL 是由您完全信任的自动重构工具生成的,而审查者的工作只是检查并确定想要这样的变更。但这些 CL 可以更大,尽管上面的一些警告(例如合并和测试)仍然适用。

### 按文件拆分 {#splitting-files}

拆分 CL 的另一种方法是对文件进行分组,这些文件需要不同的审查者,否则就是自包含的变更。

例如:您发送一个 CL 以修改协议缓冲区,另一个 CL 发送变更使用该原型的代码。您必须在代码 CL 之前提交 proto CL,但它们都可以同时进行审查。如果这样做,您可能希望通知两组审查者您编写的其他 CL,以便他们对您的变更具有更充足的上下文。

另一个例子:你发送一个 CL 用于代码更改,另一个用于使用该代码的配置或实验;如果需要,这也更容易回滚,因为配置/实验文件有时会比代码变更更快地推向生产。

## 分离出重构 {#refactoring}

通常最好在功能变更或错误修复的单独 CL 中进行重构。例如,移动和重命名类应该与修复该类中的错误的 CL 不同。审查者更容易理解每个 CL 在单独时引入的更改。

但是,修复本地变量名称等小清理可以包含在功能变更或错误修复 CL 中。如果重构大到包含在您当前的 CL 中,会使审查更加困难的话,需要开发者和审查者一起判断是否将其拆开。

## 将相关的测试代码保存在同一个 CL 中 {#test_code}

避免将测试代码拆分为单独的 CL。验证代码修改的测试应该进入相同的 CL,即使它增加了代码行数。

但是,独立的测试修改可以首先进入单独的 CL,类似于[重构指南](#refactoring)。包括:

- 使用新测试验证预先存在的已提交代码。
- 重构测试代码(例如引入辅助函数)。
- 引入更大的测试框架代码(例如集成测试)。

## 不要破坏构建 {#break}

如果您有几个相互依赖的 CL,您需要找到一种方法来确保在每次提交 CL 后整个系统能够继续运作。否则可能会在您的 CL 提交的几分钟内打破所有开发人员的构建(如果您之后的 CL 提交意外出错,时间可能会甚至更长)。

## 如果不能让它足够小 {#cant}

有时你会遇到看起来您的 CL 必须如此庞大,但这通常很少是正确的。习惯于编写小型 CL 的提交者几乎总能找到将功能分解为一系列小变更的方法。

在编写大型 CL 之前,请考虑在重构 CL 之前是否可以为更清晰的实现铺平道路。与你的同伴聊聊,看看是否有人想过如何在小型 CL 中实现这些功能。

如果以上的努力都失败了(这应该是非常罕见的),那么请在事先征得审查者的同意后提交大型 CL,好让他们提前做好大规模代码变更的心理准备。在这种情况下,做好完成审查过程需要很长一段时间的准备,要额外小心别引入错误,并且在编写测试时要更下功夫。

下一篇:[如何处理审查者评论](handling-comments.md)
Loading