├── .gitignore ├── CONTRIBUTEGUIDE.md ├── LICENSE ├── README.md ├── _config.yml └── review ├── developer ├── cl-descriptions.md ├── handling-comments.md ├── index.md └── small-cls.md ├── emergencies.md ├── index.md └── reviewer ├── comments.md ├── index.md ├── looking-for.md ├── navigate.md ├── pushback.md ├── speed.md └── standard.md /.gitignore: -------------------------------------------------------------------------------- 1 | # ide 2 | .idea 3 | *.iml -------------------------------------------------------------------------------- /CONTRIBUTEGUIDE.md: -------------------------------------------------------------------------------- 1 | ## 如何参与? 2 | 首先在github上fork本项目到自己的仓库下,然后一切改动都基于自己的仓库修改,最后提交 __Pull Request__ 将自己的改动提交到本仓库。 3 | 4 | #### 添加远程仓库 5 | `git remote add upstream git@github.com:xindoo/eng-practices-cn.git` 6 | #### 将远程仓库的更新拉取到本地 7 | `git fetch upstream` 8 | #### 将远程更新合并到本地 9 | `git rebase upstream/master` 10 | 11 | ## 翻译要求 12 | 0. [强制] pr前请先rebase到最新版本,参考以上几条git命令。 13 | 1. [强制] 每次pr只包含一个commit,可以通过`git rebase -i` 将多个commit合并成一个。 14 | 2. [建议] 适当意译,但要保证不丢失原意。 15 | 3. [注意] 为避免多人同时翻译同一篇文章,请先提PR在下方的翻译进度表中认领翻译任务,并确认翻译时间。 16 | 4. [注意] 为了保证翻译进度,如果翻译任务长时间未完成,任务将释放给其他人。 17 | 5. [注意] 为了追踪后期内容更新,请认领任务时标注当前翻译内容的git提交版本号(可以在github文件详情右上方获取到,参考README其他示例) 18 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | Attribution 3.0 Unported 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR 10 | DAMAGES RESULTING FROM ITS USE. 11 | 12 | License 13 | 14 | THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE 15 | COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY 16 | COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS 17 | AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. 18 | 19 | BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE 20 | TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY 21 | BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS 22 | CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND 23 | CONDITIONS. 24 | 25 | 1. Definitions 26 | 27 | a. "Adaptation" means a work based upon the Work, or upon the Work and 28 | other pre-existing works, such as a translation, adaptation, 29 | derivative work, arrangement of music or other alterations of a 30 | literary or artistic work, or phonogram or performance and includes 31 | cinematographic adaptations or any other form in which the Work may be 32 | recast, transformed, or adapted including in any form recognizably 33 | derived from the original, except that a work that constitutes a 34 | Collection will not be considered an Adaptation for the purpose of 35 | this License. For the avoidance of doubt, where the Work is a musical 36 | work, performance or phonogram, the synchronization of the Work in 37 | timed-relation with a moving image ("synching") will be considered an 38 | Adaptation for the purpose of this License. 39 | b. "Collection" means a collection of literary or artistic works, such as 40 | encyclopedias and anthologies, or performances, phonograms or 41 | broadcasts, or other works or subject matter other than works listed 42 | in Section 1(f) below, which, by reason of the selection and 43 | arrangement of their contents, constitute intellectual creations, in 44 | which the Work is included in its entirety in unmodified form along 45 | with one or more other contributions, each constituting separate and 46 | independent works in themselves, which together are assembled into a 47 | collective whole. A work that constitutes a Collection will not be 48 | considered an Adaptation (as defined above) for the purposes of this 49 | License. 50 | c. "Distribute" means to make available to the public the original and 51 | copies of the Work or Adaptation, as appropriate, through sale or 52 | other transfer of ownership. 53 | d. "Licensor" means the individual, individuals, entity or entities that 54 | offer(s) the Work under the terms of this License. 55 | e. "Original Author" means, in the case of a literary or artistic work, 56 | the individual, individuals, entity or entities who created the Work 57 | or if no individual or entity can be identified, the publisher; and in 58 | addition (i) in the case of a performance the actors, singers, 59 | musicians, dancers, and other persons who act, sing, deliver, declaim, 60 | play in, interpret or otherwise perform literary or artistic works or 61 | expressions of folklore; (ii) in the case of a phonogram the producer 62 | being the person or legal entity who first fixes the sounds of a 63 | performance or other sounds; and, (iii) in the case of broadcasts, the 64 | organization that transmits the broadcast. 65 | f. "Work" means the literary and/or artistic work offered under the terms 66 | of this License including without limitation any production in the 67 | literary, scientific and artistic domain, whatever may be the mode or 68 | form of its expression including digital form, such as a book, 69 | pamphlet and other writing; a lecture, address, sermon or other work 70 | of the same nature; a dramatic or dramatico-musical work; a 71 | choreographic work or entertainment in dumb show; a musical 72 | composition with or without words; a cinematographic work to which are 73 | assimilated works expressed by a process analogous to cinematography; 74 | a work of drawing, painting, architecture, sculpture, engraving or 75 | lithography; a photographic work to which are assimilated works 76 | expressed by a process analogous to photography; a work of applied 77 | art; an illustration, map, plan, sketch or three-dimensional work 78 | relative to geography, topography, architecture or science; a 79 | performance; a broadcast; a phonogram; a compilation of data to the 80 | extent it is protected as a copyrightable work; or a work performed by 81 | a variety or circus performer to the extent it is not otherwise 82 | considered a literary or artistic work. 83 | g. "You" means an individual or entity exercising rights under this 84 | License who has not previously violated the terms of this License with 85 | respect to the Work, or who has received express permission from the 86 | Licensor to exercise rights under this License despite a previous 87 | violation. 88 | h. "Publicly Perform" means to perform public recitations of the Work and 89 | to communicate to the public those public recitations, by any means or 90 | process, including by wire or wireless means or public digital 91 | performances; to make available to the public Works in such a way that 92 | members of the public may access these Works from a place and at a 93 | place individually chosen by them; to perform the Work to the public 94 | by any means or process and the communication to the public of the 95 | performances of the Work, including by public digital performance; to 96 | broadcast and rebroadcast the Work by any means including signs, 97 | sounds or images. 98 | i. "Reproduce" means to make copies of the Work by any means including 99 | without limitation by sound or visual recordings and the right of 100 | fixation and reproducing fixations of the Work, including storage of a 101 | protected performance or phonogram in digital form or other electronic 102 | medium. 103 | 104 | 2. Fair Dealing Rights. Nothing in this License is intended to reduce, 105 | limit, or restrict any uses free from copyright or rights arising from 106 | limitations or exceptions that are provided for in connection with the 107 | copyright protection under copyright law or other applicable laws. 108 | 109 | 3. License Grant. Subject to the terms and conditions of this License, 110 | Licensor hereby grants You a worldwide, royalty-free, non-exclusive, 111 | perpetual (for the duration of the applicable copyright) license to 112 | exercise the rights in the Work as stated below: 113 | 114 | a. to Reproduce the Work, to incorporate the Work into one or more 115 | Collections, and to Reproduce the Work as incorporated in the 116 | Collections; 117 | b. to create and Reproduce Adaptations provided that any such Adaptation, 118 | including any translation in any medium, takes reasonable steps to 119 | clearly label, demarcate or otherwise identify that changes were made 120 | to the original Work. For example, a translation could be marked "The 121 | original work was translated from English to Spanish," or a 122 | modification could indicate "The original work has been modified."; 123 | c. to Distribute and Publicly Perform the Work including as incorporated 124 | in Collections; and, 125 | d. to Distribute and Publicly Perform Adaptations. 126 | e. For the avoidance of doubt: 127 | 128 | i. Non-waivable Compulsory License Schemes. In those jurisdictions in 129 | which the right to collect royalties through any statutory or 130 | compulsory licensing scheme cannot be waived, the Licensor 131 | reserves the exclusive right to collect such royalties for any 132 | exercise by You of the rights granted under this License; 133 | ii. Waivable Compulsory License Schemes. In those jurisdictions in 134 | which the right to collect royalties through any statutory or 135 | compulsory licensing scheme can be waived, the Licensor waives the 136 | exclusive right to collect such royalties for any exercise by You 137 | of the rights granted under this License; and, 138 | iii. Voluntary License Schemes. The Licensor waives the right to 139 | collect royalties, whether individually or, in the event that the 140 | Licensor is a member of a collecting society that administers 141 | voluntary licensing schemes, via that society, from any exercise 142 | by You of the rights granted under this License. 143 | 144 | The above rights may be exercised in all media and formats whether now 145 | known or hereafter devised. The above rights include the right to make 146 | such modifications as are technically necessary to exercise the rights in 147 | other media and formats. Subject to Section 8(f), all rights not expressly 148 | granted by Licensor are hereby reserved. 149 | 150 | 4. Restrictions. The license granted in Section 3 above is expressly made 151 | subject to and limited by the following restrictions: 152 | 153 | a. You may Distribute or Publicly Perform the Work only under the terms 154 | of this License. You must include a copy of, or the Uniform Resource 155 | Identifier (URI) for, this License with every copy of the Work You 156 | Distribute or Publicly Perform. You may not offer or impose any terms 157 | on the Work that restrict the terms of this License or the ability of 158 | the recipient of the Work to exercise the rights granted to that 159 | recipient under the terms of the License. You may not sublicense the 160 | Work. You must keep intact all notices that refer to this License and 161 | to the disclaimer of warranties with every copy of the Work You 162 | Distribute or Publicly Perform. When You Distribute or Publicly 163 | Perform the Work, You may not impose any effective technological 164 | measures on the Work that restrict the ability of a recipient of the 165 | Work from You to exercise the rights granted to that recipient under 166 | the terms of the License. This Section 4(a) applies to the Work as 167 | incorporated in a Collection, but this does not require the Collection 168 | apart from the Work itself to be made subject to the terms of this 169 | License. If You create a Collection, upon notice from any Licensor You 170 | must, to the extent practicable, remove from the Collection any credit 171 | as required by Section 4(b), as requested. If You create an 172 | Adaptation, upon notice from any Licensor You must, to the extent 173 | practicable, remove from the Adaptation any credit as required by 174 | Section 4(b), as requested. 175 | b. If You Distribute, or Publicly Perform the Work or any Adaptations or 176 | Collections, You must, unless a request has been made pursuant to 177 | Section 4(a), keep intact all copyright notices for the Work and 178 | provide, reasonable to the medium or means You are utilizing: (i) the 179 | name of the Original Author (or pseudonym, if applicable) if supplied, 180 | and/or if the Original Author and/or Licensor designate another party 181 | or parties (e.g., a sponsor institute, publishing entity, journal) for 182 | attribution ("Attribution Parties") in Licensor's copyright notice, 183 | terms of service or by other reasonable means, the name of such party 184 | or parties; (ii) the title of the Work if supplied; (iii) to the 185 | extent reasonably practicable, the URI, if any, that Licensor 186 | specifies to be associated with the Work, unless such URI does not 187 | refer to the copyright notice or licensing information for the Work; 188 | and (iv) , consistent with Section 3(b), in the case of an Adaptation, 189 | a credit identifying the use of the Work in the Adaptation (e.g., 190 | "French translation of the Work by Original Author," or "Screenplay 191 | based on original Work by Original Author"). The credit required by 192 | this Section 4 (b) may be implemented in any reasonable manner; 193 | provided, however, that in the case of a Adaptation or Collection, at 194 | a minimum such credit will appear, if a credit for all contributing 195 | authors of the Adaptation or Collection appears, then as part of these 196 | credits and in a manner at least as prominent as the credits for the 197 | other contributing authors. For the avoidance of doubt, You may only 198 | use the credit required by this Section for the purpose of attribution 199 | in the manner set out above and, by exercising Your rights under this 200 | License, You may not implicitly or explicitly assert or imply any 201 | connection with, sponsorship or endorsement by the Original Author, 202 | Licensor and/or Attribution Parties, as appropriate, of You or Your 203 | use of the Work, without the separate, express prior written 204 | permission of the Original Author, Licensor and/or Attribution 205 | Parties. 206 | c. Except as otherwise agreed in writing by the Licensor or as may be 207 | otherwise permitted by applicable law, if You Reproduce, Distribute or 208 | Publicly Perform the Work either by itself or as part of any 209 | Adaptations or Collections, You must not distort, mutilate, modify or 210 | take other derogatory action in relation to the Work which would be 211 | prejudicial to the Original Author's honor or reputation. Licensor 212 | agrees that in those jurisdictions (e.g. Japan), in which any exercise 213 | of the right granted in Section 3(b) of this License (the right to 214 | make Adaptations) would be deemed to be a distortion, mutilation, 215 | modification or other derogatory action prejudicial to the Original 216 | Author's honor and reputation, the Licensor will waive or not assert, 217 | as appropriate, this Section, to the fullest extent permitted by the 218 | applicable national law, to enable You to reasonably exercise Your 219 | right under Section 3(b) of this License (right to make Adaptations) 220 | but not otherwise. 221 | 222 | 5. Representations, Warranties and Disclaimer 223 | 224 | UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR 225 | OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY 226 | KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, 227 | INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, 228 | FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF 229 | LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, 230 | WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION 231 | OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. 232 | 233 | 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE 234 | LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR 235 | ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES 236 | ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS 237 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 238 | 239 | 7. Termination 240 | 241 | a. This License and the rights granted hereunder will terminate 242 | automatically upon any breach by You of the terms of this License. 243 | Individuals or entities who have received Adaptations or Collections 244 | from You under this License, however, will not have their licenses 245 | terminated provided such individuals or entities remain in full 246 | compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will 247 | survive any termination of this License. 248 | b. Subject to the above terms and conditions, the license granted here is 249 | perpetual (for the duration of the applicable copyright in the Work). 250 | Notwithstanding the above, Licensor reserves the right to release the 251 | Work under different license terms or to stop distributing the Work at 252 | any time; provided, however that any such election will not serve to 253 | withdraw this License (or any other license that has been, or is 254 | required to be, granted under the terms of this License), and this 255 | License will continue in full force and effect unless terminated as 256 | stated above. 257 | 258 | 8. Miscellaneous 259 | 260 | a. Each time You Distribute or Publicly Perform the Work or a Collection, 261 | the Licensor offers to the recipient a license to the Work on the same 262 | terms and conditions as the license granted to You under this License. 263 | b. Each time You Distribute or Publicly Perform an Adaptation, Licensor 264 | offers to the recipient a license to the original Work on the same 265 | terms and conditions as the license granted to You under this License. 266 | c. If any provision of this License is invalid or unenforceable under 267 | applicable law, it shall not affect the validity or enforceability of 268 | the remainder of the terms of this License, and without further action 269 | by the parties to this agreement, such provision shall be reformed to 270 | the minimum extent necessary to make such provision valid and 271 | enforceable. 272 | d. No term or provision of this License shall be deemed waived and no 273 | breach consented to unless such waiver or consent shall be in writing 274 | and signed by the party to be charged with such waiver or consent. 275 | e. This License constitutes the entire agreement between the parties with 276 | respect to the Work licensed here. There are no understandings, 277 | agreements or representations with respect to the Work not specified 278 | here. Licensor shall not be bound by any additional provisions that 279 | may appear in any communication from You. This License may not be 280 | modified without the mutual written agreement of the Licensor and You. 281 | f. The rights granted under, and the subject matter referenced, in this 282 | License were drafted utilizing the terminology of the Berne Convention 283 | for the Protection of Literary and Artistic Works (as amended on 284 | September 28, 1979), the Rome Convention of 1961, the WIPO Copyright 285 | Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 286 | and the Universal Copyright Convention (as revised on July 24, 1971). 287 | These rights and subject matter take effect in the relevant 288 | jurisdiction in which the License terms are sought to be enforced 289 | according to the corresponding provisions of the implementation of 290 | those treaty provisions in the applicable national law. If the 291 | standard suite of rights granted under applicable copyright law 292 | includes additional rights not granted under this License, such 293 | additional rights are deemed to be included in the License; this 294 | License is not intended to restrict the license of any rights under 295 | applicable law. 296 | 297 | 298 | Creative Commons Notice 299 | 300 | Creative Commons is not a party to this License, and makes no warranty 301 | whatsoever in connection with the Work. Creative Commons will not be 302 | liable to You or any party on any legal theory for any damages 303 | whatsoever, including without limitation any general, special, 304 | incidental or consequential damages arising in connection to this 305 | license. Notwithstanding the foregoing two (2) sentences, if Creative 306 | Commons has expressly identified itself as the Licensor hereunder, it 307 | shall have all rights and obligations of Licensor. 308 | 309 | Except for the limited purpose of indicating to the public that the 310 | Work is licensed under the CCPL, Creative Commons does not authorize 311 | the use by either party of the trademark "Creative Commons" or any 312 | related trademark or logo of Creative Commons without the prior 313 | written consent of Creative Commons. Any permitted use will be in 314 | compliance with Creative Commons' then-current trademark usage 315 | guidelines, as may be published on its website or otherwise made 316 | available upon request from time to time. For the avoidance of doubt, 317 | this trademark restriction does not form part of this License. 318 | 319 | Creative Commons may be contacted at https://creativecommons.org/. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 本文档翻译自Google的[eng-practices](https://github.com/google/eng-practices),译者水平有限,如有发现翻译错误可以提issue或者pr。 2 | # 谷歌工程实践文档 3 | 4 | 谷歌在很多语言和项目上都有大量的工程实践经验。这些文档代表了我们长期以来开发的各种最佳实践的经验。开源项目或其他组织可能会从这些知识中受益,这些文档代表了我们长期以来开发的各种最佳实践的集体经验。开源项目或其他组织可能会从这些知识中受益,因此我们努力在可能的情况下公开这些经验。 5 | 6 | 当前文档包含以下内容: 7 | 8 | * [谷歌代码评审指南](review/index.md), 包含两个子章节: 9 | * [评审者指南](review/reviewer/index.md) 10 | * [开发者指南](review/developer/index.md) 11 | 12 | ## 术语 13 | 14 | 部分文档中会用到一些谷歌内部的术语,特在此说明: 15 | 16 | * **CL**: "changelist"的缩写,代表已经进入版本控制软件或者正在进行代码评审的变更。 17 | 其他组织经常称为"change"或者"patch"。 18 | * **LGTM**: "Looks Good to Me."的缩写,评审者批准CL时会这么说。 19 | 20 | ### 如何参与翻译 21 | 参考[翻译指南](CONTRIBUTEGUIDE.md) 22 | 23 | ## 中文贡献者 24 | [@xindoo](https://github.com/xindoo) [@LargeOrange](https://github.com/LargeOrange) [@hanfeisun](https://github.com/hanfeisun) [@Ensteinjun](https://github.com/Ensteinjun) [@wangzhuo0978](https://github.com/wangzhuo0978) 25 | 26 | 27 | ## 许可协议 28 | 29 | 本文遵循[CC-By 3.0协议](https://creativecommons.org/licenses/by/3.0/) 您可以自由地: 30 | 31 | - 共享 - 在任何媒介以任何形式复制、发行本作品 32 | - 演绎 - 修改、转换或以本作品为基础进行创作在任何用途下,甚至商业目的。 33 | 34 | Creative Commons License 35 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-slate 2 | -------------------------------------------------------------------------------- /review/developer/cl-descriptions.md: -------------------------------------------------------------------------------- 1 | # 写一个好的CL描述 2 | 3 | 一个CL描述是做了**什么**更改以及**为什么**的公开记录。 4 | 它将成为我们版本控制历史的永久组成部分,多年来除你的评审者以外,还可能有数百人会阅读它。 5 | 将来的开发者将会基于它的描述来搜索你的CL。 6 | 将来可能会有人由于没有现成的细节,而根据他模糊的记忆来寻找你的改变。 7 | 如果所有重要的细节都在代码中而不是描述中,那么他们将很难定位你的CL。 8 | 9 | ## 第一行 10 | 11 | * 言简意赅 12 | * 语义完整 13 | * 段落分明 14 | 15 | CL描述的**第一行**应该是对CL正在**做的***具体*工作的简短总结,紧跟一个空行。 16 | 17 | 这是应该出现在版本控制历史摘要中的内容,它应该提供足够的信息,以便将来搜索代码的人必阅读整个CL或完整的描述来理解CL实际上“做了”什么,或者它与其他CLs有什么不同。也就是说,第一行应该是独立的,允许读者更快地了解代码历史。 18 | 19 | 尽量保持第一行言简意赅、直奔主题。让读者清晰且觉得使用才是最重要的。 20 | 按照传统,CL描述的第一行是一个完整的句子,就像它是一个命令(一个祈使句)。 21 | 例如,说\"**Delete** the FizzBuzz RPC and **replace** it with the new system.",而不是\"**Deleting** the FizzBuzz RPC and **replacing** it with the new system."。 22 | 不过,你不必把其余的描述写成祈使句。 23 | 24 | ## 正文内容丰富 25 | 26 | 其余描述应该是具有丰富的内容。它可能包括对正在解决的问题的简要描述,以及为什么这是最好的方法。 如果这种方法有任何缺点,就应该提到。将相关的背景信息(例如bug数目,基准测试结果),以及设计文档的链接。 27 | 如果你想加一些链接来指向其他内容,请注意未来的阅读者可能因为没有权限看不到这些内容,所以尽可能地把上下文都写在CL中以方便评审者和未来CL的阅读者。 28 | 另外,即使是很小的CL也值得关注细节。请将来龙去脉放入CL中。 29 | 30 | ## 反例 31 | "Fix bug"是一个不充分的CL描述。是什么bug?你是怎么修复它的? 32 | 其他一些类似的不好的CL描述: 33 | 34 | - "Fix build." 35 | - "Add patch." 36 | - "Moving code from A to B." 37 | - "Phase 1." 38 | - "Add convenience functions." 39 | - "kill weird URLs." 40 | 41 | 也有一些真实的CL描述,虽然简短,但没有提供任何有用的信息。 42 | 43 | ## 好的CL描述 44 | 45 | 这里有一些好的CL描述的样例. 46 | 47 | ### 功能变更 48 | 49 | > rpc: remove size limit on RPC server message freelist. 50 | > 51 | > Servers like FizzBuzz have very large messages and would benefit from reuse. 52 | > Make the freelist larger, and add a goroutine that frees the freelist entries 53 | > slowly over time, so that idle servers eventually release all freelist 54 | > entries. 55 | 56 | 前几个词描述了CL描述实际做了什么。其余描述在说明解决的问题,为什么这是一个好的方案,以及具体实现的细节。 57 | 58 | ### 重构 59 | 60 | > Construct a Task with a TimeKeeper to use its TimeStr and Now methods. 61 | > 62 | > Add a Now method to Task, so the borglet() getter method can be removed (which 63 | > was only used by OOMCandidate to call borglet's Now method). This replaces the 64 | > methods on Borglet that delegate to a TimeKeeper. 65 | > 66 | > Allowing Tasks to supply Now is a step toward eliminating the dependency on 67 | > Borglet. Eventually, collaborators that depend on getting Now from the Task 68 | > should be changed to use a TimeKeeper directly, but this has been an 69 | > accommodation to refactoring in small steps. 70 | > 71 | > Continuing the long-range goal of refactoring the Borglet Hierarchy. 72 | 73 | 第一行描述了CL做了什么,以及它是如何与过去发生变化的。 74 | 其余的描述将讨论具体的实现、CL的来龙去脉、解决方案的不理想以及未来可能的方向。 75 | 它同样是解释*为什么*要进行这个修改。 76 | 77 | ### 需要上下文的小CL 78 | 79 | > Create a Python3 build rule for status.py. 80 | > 81 | > This allows consumers who are already using this as in Python3 to depend on a 82 | > rule that is next to the original status build rule instead of somewhere in 83 | > their own tree. It encourages new consumers to use Python3 if they can, 84 | > instead of Python2, and significantly simplifies some automated build file 85 | > refactoring tools being worked on currently. 86 | 87 | 88 | 第一句描述了实际做了什么。其余的描述解释了*为什么*要进行更改,并给了reviewer很多背景。 89 | 90 | ## 生成CL描述 91 | 虽然有些CL是工具生成的,但是只要可能,CL的描述也应该遵循本规范,始终保持言简意赅,CL的描述主体应该包含有助于未来查阅代码的人理解整个CL作用的有用信息。 92 | 93 | ## 在提交CL之前,请检查描述 94 | 95 | 在Review期间CL可能会经历重大改变。在提交CL之前,有必要review CL描述,以确保描述仍然反映CL所做的事情。 96 | 97 | 下一章: [简短的CL](small-cls.md) 98 | -------------------------------------------------------------------------------- /review/developer/handling-comments.md: -------------------------------------------------------------------------------- 1 | # 如何处理评审者的评论 2 | 3 | 当你提交了一个变更做代码评审时,很可能你都会收到评审者在变更中的评论。这里有一些处理这些评论的建议。 4 | 5 | ## 不要掺杂个人情感 6 | 7 | 代码评审的目标是维护代码库和产品的质量。如果评审者批评了你的代码,可以理解为他们在帮你、帮整个代码库、甚至是帮整个公司,而不是攻击你或者是质疑你的能力。 8 | 9 | 有时候评审者会情绪低落,然后在评论中说出一些令人沮丧的话,虽然评审者这样做不对,但作为开发者你应当有心理准备。问问你自己,“评审者试图与我交流的建设性意见是什么?” 然后照他们说的那些去做。 10 | 11 | **永远不要回应充满怒气的评论**,代码评审工具中违反职业礼仪的情况永远存在。如果你真的忍无可忍,建议先离开电脑一会儿,或者干一些其他的事,等心情平复下来再回复。 12 | 13 | 通常,如果评审者没有以礼貌的方式提供反馈,请亲自向他们解释。如果你无法亲自或者通过视频和他们联系,就向他们发一份私人邮件。 友好地告诉他们你不喜欢的事情以及你希望他们做些什么。 如果他们也以非建设性的方式对此私密讨论做出回应,或者没有起到预期的作用,请酌情上报给您的经理。如果他们已经以不礼貌的方式回应,或者没有取得预期的效果,视情况汇报给你的经理。 14 | 15 | ## 修复代码 16 | 17 | 如果评审者说他们理解不了你代码中的某些内容,你首先应该把代码写清晰。如果让代码更清晰,添加注释来解释清楚代码的逻辑。 如果评论似乎毫无意义,那么您的答复应该只是代码查看工具中的解释。 18 | 19 | 如果评审者无法理解你的某部分代码,那边可能未来的阅读者也可能理解不了。在代码评审工具中回应帮不了未来的读者,但是代码中的注释可以。 20 | 21 | ## 自我反思 22 | 23 | 写一个变更会花费你很大的精力,提交代码评审时会感觉如释负重,而且自己也相当确定所有工作已经做完了。所以当评审者提出改进建议时,你很容易认为那些都是错的,或者认为是评审者给你不必要的阻挠,再或者觉得评审者应该让你提交变更。 无论如何,**不管你怎么想**,花点时间回想下评审者给你的反馈有助于提升公司的代码质量。你始终问下自己“如果评审者是对的呢?” 24 | 25 | 如果你回答不了评审者的问题,那可能说明评审者的评论不够清楚。 26 | 27 | 如果你认真考虑过后依旧认为你是对的,放心大胆地解释清楚为什么你的方法对公司更有利。通常,评审者只是提供*建议*,并且希望你能思考出更好的方法。也许你已经知道一些评审者不知道的关于用户、代码库、或者变更,把这些都写下来,给评审者更多的上下文信息,通常你都可以根据某些事实和评审者达成某些共识。 28 | 29 | ## 解决冲突 30 | 31 | 解决冲突的第一步,和你的评审者达成共识,如果无法达成共识,参阅[代码评审的标准](../reviewer/standard.md)获取更多内容。 32 | 33 | -------------------------------------------------------------------------------- /review/developer/index.md: -------------------------------------------------------------------------------- 1 | # CL开发者指南 —— 更好的通过代码评审 2 | 3 | 这一节介绍开发者CL的相关实践,帮助你更快地通过代码评审,并获得更高质量的结果。你不必全部读完,但是它们对每个谷歌开发人员都非常有用,当你全部阅读完成后会觉得非常有用 4 | 5 | - [写好CL描述](cl-descriptions.md) 6 | - [简短化CL](small-cls.md) 7 | - [如何处理评审者的建议?](handling-comments.md) 8 | 9 | 也请阅读 [怎样去做代码评审](../reviewer/), 了解更多评审者相关的细节。 10 | 11 | 12 | -------------------------------------------------------------------------------- /review/developer/small-cls.md: -------------------------------------------------------------------------------- 1 | # 简短化的CL 2 | 3 | 4 | ## 为什么要写成一系列简短的CL? 5 | 6 | 简短的CL有这些好处: 7 | 8 | - **代码评审更快** 与比起花30分钟评审一个大型的CL相比,对评审者来说花5分钟审查一系列小的CL更加容易. 9 | - **评审更加彻底。** 进行较大的更改后,审阅者和作者往往会因大量详细评论的来回移动而感到沮丧,有时这些评论会漏掉或遗漏重要的观点。 10 | - **减少导致bug的可能性。** 由于您所做的更改较少,因此您和您的审阅者更容易有效地推断出CL的影响,并查看是否导致bug。 11 | - **减少不必要的工作** 当你写了一个巨大的CL,然后评审者觉得你总体方向错了,这会导致你浪费大量的工作。 12 | - **更方便合并代码** 因为大型的CL会导致大量的冲突,因此合并大型的CL会浪费很多时间,并且这将会是你经常做的工作。 13 | - **有助于你作出更好的设计** 优雅的设计并且完善一个小的改动比大的改动更加容易 14 | - **降低评审者的难度** 提审部分改动,不会影响你继续编码。 15 | - **回滚更容易** 大型CL很有可能会在初始CL提交和回滚CL之间更新修改文件,从而使回滚变得复杂(中型CL也可能也需要回滚可能也会这样)。 16 | 17 | 注意! **评审者可以因为你的改动过于巨大直接拒绝掉你**,通常他们会感谢您的贡献,但要求您以某种方式使它成为一系列较小的CL。不管是你把这些改动拆分成小的改动,还是和评审者争论让他接受都会耗费你大量的时间。但是编写小型改动就不会有这样的问题。 18 | 19 | ## 怎么样算简短? 20 | 21 | 通常,一个CL合适的大小是:只包含**一个独立的更改**。 这意味着: 22 | 23 | - CL所做的最小更改仅解决了**一件事情**。 通常,这只是功能的一部分,而不是一次完整的功能。 通常,宁可编写过小的CL也不要写太大的CL。你可以和你的评审者商量找到合适的尺度。 24 | - 审阅者需要了解的有关CL的所有内容(将来的开发除外)都在CL,CL的描述,现有代码库或他们已经查看过的CL中。 25 | - CL应当包含相关的测试代码(#test_code) 26 | - CL合进去后,对于用户和开发者而言,系统能继续正常工作。 27 | - CL不够小的话会导致其难以理解。如果你新增加了api,那么在同一个CL应该包括这个api用到的方法,以便评审者更好的理解。也能防止检入没有用的api。 28 | 29 | 多大算大,没有一个明确的要求。 一般100行是一个合理的大小,而1000行太大,当然这也取决于您的审阅者的判断。 更改分布的文件数量也会影响其“大小”。 可以在一个文件中进行200行的更改,但是将其分布在50个文件中通常会太大。 30 | 31 | 请记住,尽管从您开始编写代码起就一直与您紧密联系,但审阅者通常没有上下文。 对您来说,看起来像可接受大小的CL可能会让您的审阅者不知所措。毫无疑问,尽可能把CL些小是正确的。评审者很少抱怨CL太小 32 | 33 | ## 什么时候大型的CL也是可以的? 34 | 35 | 在某些情况下,较大的更改没有那么糟糕: 36 | 37 | - 通常,您可以将整个文件的删除视为更改的一行,因为它不会花费审阅者很长时间来审阅。 38 | - 有时,您完全信任的自动重构工具已经生成了一个较大的CL,而审阅者的工作只是检查健全性,然后指出他们认为需要修改的地方。 这些CL可能更大,尽管会有一些风险(例如合并和测试)仍然适用。 39 | 40 | ### 按文件分类 41 | 42 | 拆分CL的另一种方法是通过将文件分组,如果这些文件将是独立的更改,可以分配各不同的审阅者。 43 | 44 | 比如: 你提交一个修改的CL,创建一个修改的缓冲区,另一个CL的代码修改也可以提交到这里面。你必须按照顺序提交CL,但是审阅者可以同时进行审阅. 如果这么做,你需要尽可能告诉所有审阅者另一个CL的信息,以便他们能得到上线文信息。 45 | 46 | 另一个示例:您发送一个CL进行代码更改,而另一个CL则发送使用该代码的配置或实验; 如果需要,这也更容易回滚,因为有时将配置/实验文件推送到生产环境中比更改代码更快。 47 | 48 | ## 把代码重构分离出来 49 | 50 | 通常重构最好不要和功能修改或者bug fix一起提CL。比如移动或者重命名一个Class,最好和这个Class的bug fix分开提CL。这样对于审阅者来说,理解每个CL单独引入的更改要容易得多。 51 | 52 | 不过一些小的代码清理工作比如变量重命名可以包含在功能修改或者bug fix的CL种。 这取决于开发者和审阅者的判断,当然如果巨大的重构包含在同一个CL中会大大增加审阅的难度。 53 | 54 | ## 将相关的测试代码保存在同一CL中 55 | 56 | 避免将测试代码拆分为单独的CL。 验证代码修改的测试应该进入相同的CL,即使这样做会增加代码行数。 57 | 58 | 但是根据[重构准则](#refactoring),独立的测试修改可以单独写入CL。比如 59 | 60 | * 使用新测试验证先前存在的提交代码。 61 | * 重构测试代码(例如,引入辅助函数)。 62 | * 引入更大的测试框架代码(例如集成测试)。 63 | 64 | ## 不要破坏结构 65 | 66 | 如果您有多个相互依赖的CL,则需要找到一种方法来确保在提交每个CL之后整个系统都能正常工作。 否则,可能破坏代码结构导致后面的开发者浪费大量的时间等你的提交(如果这些CL提交出了问题,则更长的时间)。 67 | 68 | ## 小到不能再小 69 | 70 | 有时候,您会遇到CL很大的情况。 这很少是真的。 练习编写小型CL的作者几乎总是*可以*找到一种将功能分解为一系列小的更改的方法。 71 | 72 | 在写大型CL之前,思考下是不是能够将重构分离出来,这是一个更加清晰的思路。多和你的队友交流学习下他们对缩小CL的实践和方法。 73 | 74 | 如果所有这些选项都失败了(这种情况很少见),那么请事先获得您的审阅者的同意,告诉他们一个巨大的CL将要来临。 在这种情况下,审查过程会耗费极其长的时间,这样请花费更多的时间去写测试代码,避免引入bug。 75 | 76 | 下一节: [怎么处理审阅者的评论](handling-comments.md) 77 | -------------------------------------------------------------------------------- /review/emergencies.md: -------------------------------------------------------------------------------- 1 | 2 | # 紧急情况 3 | 4 | 有时, 会出现紧急的代码修改, 对于这些修改需要尽可能快速的通过整个代码评审流程 5 | 6 | ## 紧急情况的定义 {#what} 7 | 8 | 紧急情况下的修改应该是小范围代码的改动,例如:能够使得重要提交被继续进行而非回滚, 修复显著影响用户体验的bug, 处理紧急的法律问题, 9 | 修复可能产生重大影响的安全漏洞等. 10 | 11 | 在紧急情况下, 我们十分关心整个代码的审查速度, 不单单是[响应速度](reviewer/speed.md), *仅在这种情况下*, 评审者应该更加注重评审速度和 12 | 代码的正确性(能否解决当前的紧急情况), 显然,当有紧急评审情况出现时, 对该情况的评审应处于最高优先状态. 13 | 14 | 并且, 在修复紧急情况之后, 应该再次查看CLs进行[更加彻底的代码检查](reviewer/looking-for.md). 15 | 16 | ## 哪些不属于紧急情况? {#not} 17 | 18 | 以下这些例子均不属于紧急情况: 19 | 20 | - 期望在本周发布新的版本更新, 而不是在下一周 (除非一些特定原因导致必须在某个截止日期之前发布, 例如同合作伙伴之间有相关协定) 21 | - 开发人员花费了很长的时间开发某个功能, 希望自己的修改得到通过 22 | - 审阅人员处在另一个时区的深夜时间或者他们均远在异地 23 | - 处在周末休息前的最后一天(如星期五), 期望能够在开发人员休息之前通过代码审阅 24 | - 一位管理人员说审阅必须完成或者因为软性截至日期的原因导致CL审阅安排在今天 25 | - 因为测试或者构建失败导致回滚的CL 26 | 等等 27 | 28 | ## Hard Deadline(硬截止期限)的定义是什么? {#deadlines} 29 | 30 | 硬截止期限指的是:如果你错过这个时间会导致一些灾难性质的的事情发生, 例如: 31 | 32 | - 合同规定必须在特定时间之前提交CL 33 | - 你的产品没有在特定时间之前发布将会导致在市场上的完全失败 34 | - 一些硬件制造商一年只发布一次新的硬件, 如果你没有在截止时间之前提交你的代码, 将会是灾难的, 具体取决于您将发布的代码类型. 35 | 36 | 将发布推迟一个星期并不会产生灾难性的后果. 错过一个重要的会议有可能会导致灾难性的后果,不过多数都不会 37 | 38 | 大部分的截止时间都是软截止期限(soft deadlines) 非硬截止时间(hard deadlines). 表示期望在某个时间之前完成某项功能的开发. 39 | 这个时间是重要的, 但是不能为了在这个时间之前开发完成而牺牲了代码的健壮性. 40 | 41 | 如果发布的周期较长(几周), 为了在下一个发布周期之前发布新的功能,你可能会忍不住牺牲代码审阅的质量. 42 | 然而, 如果重复这种模式. 容易导致积累过多的"技术债". 如果开发人员习惯性地在发布周期快结束之前提交CL,并让审核草草了事, 43 | 那就说明团队亟需修改工作流程, 以保证大的功能改动在整个发布周期中尽早完成,进而确保这些改动能有充足的时间来进行审阅. 44 | -------------------------------------------------------------------------------- /review/index.md: -------------------------------------------------------------------------------- 1 | # 代码评审开发者指南 2 | 3 | ## 介绍 4 | 代码评审是一些人提交一些代码片段,供另外一些人审阅的流程。 5 | 在谷歌,我们都是通过代码评审来保证代码和产品的质量。 6 | 这篇文档是对谷歌代码评审流程和策略的权威描述。 7 | 这一页是我们代码评审过程的概述。这篇指南其他有两个大的部分,分别是: 8 | 9 | - **[评审者指南](reviewer/)**: 代码评审者的详细指南。 10 | - **[开发者指南](developer/)**: 提交代码评审的开发者的详细指南。 11 | 12 | ## 代码评审者需要关注什么? 13 | 14 | 代码评审者需要关注: 15 | - **设计**: 代码是否设计良好并且适合你们的系统? 16 | - **功能性**: 代码功能是否和开发者预期一致?这种方式是否对用户友好? 17 | - **复杂性**: 代码能不能更简单? 其他开发者能否快速理解并在未来很容易地使用这段代码? 18 | - **测试**: 这段代码是否有正确和设计良好的自动化测试样例? 19 | - **命名**: 开发者有没有正确地对变量、类、方法等命名? 20 | - **注释**: 注释是否清晰有用? 21 | - **代码风格**: 代码风格是否遵循[谷歌代码风格指南](http://google.github.io/styleguide/)? 22 | - **文档**: 开发者是否更新了相关文档? 23 | 24 | 参考 **[代码评审者指南](reviewer/)** 获取更多信息。 25 | 26 | ### 挑选最适合的代码评审者 27 | 通常而言,你都希望找个一个*最合适*的评审者在合理的时间里对你的变更作出评审。 28 | 最合适的评审者是那些能对你代码做出最全面最准确评价的人,一般情况下都是代码的维护者(他可能在所有者列表里也有可能不在)。 有时这意味着要不同的人阅读不同的部分。 29 | 如果你找到理想的评审者但他没有时间,你也至少应该抄送他。 30 | 31 | ### 亲自评审 32 | 如果你是和某个合格的代码评审者结对写的代码,那么这段代码可以认为已经通过评审了。 33 | 你也可以以问答的方式亲自参与代码评审。 34 | 35 | ## 参见 36 | - **[评审者指南](reviewer/)**: 代码评审者的详细指南。 37 | - **[开发者指南](developer/)**: 提交变更评审的开发者的详细指南。 38 | -------------------------------------------------------------------------------- /review/reviewer/comments.md: -------------------------------------------------------------------------------- 1 | # 怎样写代码评论 2 | 3 | ## 概要 4 | 5 | - 礼貌 6 | - 解释你的观点. 7 | - 明确指出方向和问题,帮助开发人员去权衡作出决定. 8 | - 鼓励开发人员通过注释和精简代码来解决你的困惑而不是通过解释 9 | 10 | ## 礼貌 11 | 12 | 通常来说当你代码评审代码时保持[礼貌和尊重](https://chromium.googlesource.com/chromium/src/+/master/docs/cr_respect.md)很重要,这也能使开发人员更加清晰,得到更多帮助。这样是为了保证你的代码评论仅仅针对的是*code*而不是针对*开发人员*。你不必一直这么去做,但是当你的评论会让开发人员生气或者产生争执时有必要这么去做。比如: 13 | 14 | 反例: "**你**为什么会在这里使用线程,这样做难道会有任何好处?" 15 | 16 | 正例: "我并没有发现这个并发模块给程序带来了多少帮助,并且还增加了程序的复杂性,因此我认为这段代码最好是用单线程而不是多线程。 17 | 18 | ## 解释清楚原因 19 | 20 | 从上面“好”的例子当中你能发现,这样有助于开发人员理解*为什么*你写了这些评注。你不一定非得包含这些信息在你的评注里面,但是适当的多解释你的意图或者多给出一些提升代码质量的建议都是非常好的实践。 21 | 22 | ## 给予指导 23 | 24 | **通常来说修复CL是开发人员的职责而不是评审人员的**。你不需要向开发人员提供详细的解决方案或者代码。 25 | 26 | 但是这并不意味着评审员就不应该提供帮助。你需要在指出问题和提供直接指导之间找到平衡。指出问题并且帮助开发人员决策能够帮助开发人员学同事让代码评审变得更加简单。这样也能产生更好的方案,因为开发人员比评审者更加了解代码。 27 | 28 | 尽管这样,有时候直接给出指导,建议甚至是代码更有帮助。代码评审的主要目的是尽可能得到最好的CL。其次是提高开发人员的技能这样就能减少以后评审的次数。 29 | 30 | ## 接受解释 31 | 32 | 与其要求让开发人员解释一段你看不懂的代码,其实更应该做的是**让他们重写代码,让代码更清晰**。当一段代码不是太过于复杂的时候通过加一些注释偶尔也是一种不错的做法。 33 | 34 | **解释仅仅是写在代码评审工具里的,不利于将来的代码阅读者。**只有极少数情况是可行的,比如你对你评审的需求不太熟悉,但是开发人员解释的是大多数人都知道的。 35 | 36 | 下一节: [处理代码评审中的反驳](pushback.md) 37 | -------------------------------------------------------------------------------- /review/reviewer/index.md: -------------------------------------------------------------------------------- 1 | # 如何做代码评审? 2 | 3 | 本节中介绍了基于长期经验总结的代码评审最佳实践。所有内容都在同一个章节里,但被分为了好多子章节。虽然你不必通读一遍,但认真看一遍对你自己和整个团队都会有很大的益处。 4 | 5 | - [代码评审的标准](standard.md) 6 | - [代码评审应该关注什么?](looking-for.md) 7 | - [代码评审的步骤](navigate.md) 8 | - [代码评审的速度](speed.md) 9 | - [在代码评审中如何写评论](comments.md) 10 | - [处理代码评审中的反驳](pushback.md) 11 | 12 | 参见[开发者指南](../developer/), 为开发者提供了详细的代码评审指南。 13 | -------------------------------------------------------------------------------- /review/reviewer/looking-for.md: -------------------------------------------------------------------------------- 1 | # 代码评审应该关注什么? 2 | 3 | 注意:当我们考虑以下点时,应当始终遵循[代码评审标准](standard.md)。 4 | 5 | ## 设计 6 | 7 | 代码评审中最重要的一个点就是把握住变更中的整体设计。变更中各个部分的代码交互是否正常?整个改动是否属于你负责的代码库?是否和你系统中其他部分交互正常?现在是否是添加整个功能的恰当时间? 8 | 9 | ## 功能性 10 | 11 | 开发者在这个变更中想做什么? 开发人员打算为该代码的用户带来什么好处?(这里”用户“是指受变更影响到的实际用户,和将来会使用到这些代码的开发者) 12 | 13 | 重要的是,我们希望开发者能充分测试代码,以确保代码在代码评审期间正常运行。但无论如何,你作为审查者也要考虑一些特殊情况,像是有些并发问题。站在用户的角度,确保你正在看的代码没有bug。 14 | 15 | 你可以验证变更,尤其是在有面向用户的影响时,评审者应该仔细检查整个变更。有时候单纯看代码很难理解这个变更如何影响到用户,这种情况下如果你不方便自己在CL中打补丁并亲自尝试,你可以让开发者为你提供一个功能性的demo。 16 | 17 | 另一个在代码评审时需要特别关注的点是,CL中是否有 **并发编程**,并发理论上可能会导致死锁或资源争抢,这种问题在代码运行时很难被检测出来,所以需要有人(开发者和评审者)仔细考虑整个逻辑,以确保不会引入线程安全的问题。(所以除了死锁和资源争抢之外,增加代码评审复杂度也可以成为拒绝使用多线程模型的一个理由。) 18 | 19 | ## 复杂性 20 | 21 | 变更是否比预期的更复杂?检测变更的每个级别,是否个别行太复杂?功能是否太复杂?类是否太复杂?”复杂“意味着**代码阅读者很难快速理解代码**,也可意味着**开发者尝试调用或修改此代码时可能会引入bug。**。 22 | 23 | 一个典型的复杂性问题就是 **过度设计**,当开发者让代码变得更通用,或者增加了许多当前不需要的功能时,评审者应该额外注意是否过度设计。鼓励开发者解决*现在*遇到的问题,而不是揣测未来可能遇到的问题。未来的问题应当在遇到时解决,到那个时候你才能看到问题本质和实际需求。 24 | 25 | ## 测试 26 | 27 | 开发人员应当进行单元测试、集成测试或端到端测试。一般来说,变更中应该包含测试,除非这个变更只是为了处理[紧急情况](../emergencies.md)。 28 | 29 | 确保变更中的测试是正确、合理和有用的。因为测试本身无法测试自己,而且我们很少会为测试编写测试,所以必须确保测试是有效的。 30 | 31 | 如果代码出了问题,测试会失败吗?如果代码发生改动,它们会误报吗?每一个测试都有断言吗?是否按照不同的测试方法对测试进行分类? 32 | 33 | 记住,不要以为测试不是二进制中的一部分就不关注其复杂度。 34 | ## 命名 35 | 开发人员是否使用了良好的命名方式?好的命名要能够充分表达一个项(变量、类名等)是什么或者用来做什么,但又不至于让人难以阅读。 36 | 37 | ## 注释 38 | 39 | 开发者有没有写出清晰易懂的注释?所有的注释都是必要的吗? 通常注释应该解释清楚**为什么这么做**,而不是*做了什么*。如果代码不清晰,不能清楚地解释自己,那么代码可以写的更简单。当然也有些例外(比如正则表达式和复杂的算法,如果能够解释清楚他们在做什么,肯定会让阅读代码的人受益良多),但大多数注释应该指代码中没有包含的信息,比如代码背后的决策。 40 | 41 | 变更中附带的其他注释也很重要,比如列出一个可以移除的待办事项,或者一个不要做出代码变更的建议,等等。 42 | 43 | 注意,注释不同于类、模块或函数*文档*,文档是为了说明代码片段如何使用和使用时代码的行为。 44 | 45 | ## 风格 46 | 在谷歌内部,主流语言甚至部分非主流语言都有[编码风格指南](http://google.github.io/styleguide/) ,确保变更遵循了这些风格规范。 47 | 48 | 如果你想对风格指南中没有提及的风格做出改进,可以在注释前面加上“Nit:”,让开发人员知道这是一个你认为可以改进的地方,但不是强制性的。但请不要只是基于个人偏好来阻止变更的提交。 49 | 50 | 开发人员不应该将风格变更与其他变更放在一起,这样很难看出变更里有哪些变化,让合并和回滚变得更加复杂,也会导致更多的其他问题。如果开发者想要重新格式化整个文件,让他们将重新格式化后的文件作为单独的变更,并将功能变更作为另一个变更。 51 | 52 | ## 文档 53 | 54 | 如果变更改变了用户构建、测试、交互或者发布代码相关的逻辑,检测是否也更新了相关文档,包括READMEs, g3doc页面,以及任何相关文档。如果开发者删除或者弃用某些代码,考虑是否也应该删除相关文档。如果文档有确实,让开发者补充。 55 | 56 | ## 代码细节 57 | 58 | 查看你整个代码评审中的每一行代码,比如你可以扫到的数据文件,生成的代码或大型数据结构,但不要只扫一遍手写的类,函数或者代码块,然后假设它们都能正常运行。显然,有些代码需要仔细检查,这完全取决于你,但你至少应该*理解*所有的代码都在做什么。 59 | 60 | 如果你很难看懂代码,导致代码评审的速度慢了下来,你要让开发者知道,并且在Review前澄清原因。在谷歌,我们有最优秀的工程师,你也是其中之一。如果你都看不懂,很可能其他人也看不懂。所以要求开发者理清代码逻辑也是在帮助未来的开发者。 61 | 62 | 如果你理解代码,但又觉得没有资格做代码评审,确保有资格的变更评审人员在代码评审时考虑到了安全性、并发性、可访问性、国际化等问题。 63 | 64 | ## 上下文 65 | 66 | 看改动上下文代码对代码评审很有帮助,因为通常代码评审工具只会显示改动部分上下几行代码,但有时你必须查看整个文件确保这次变更可以正常运行。例如,你可能看到加了4行代码,但是看到整个文件时才会发现这加的4行代码是在一个50多行的方法里,这个方法现在应该被拆分为多个小的方法了。 67 | 68 | 代码评审时考虑到整个系统的上下文也很重要,这次改动提升了系统健康度?或者增加了系统复杂性?少了测试用例?…… **不要通过哪些会损害系统健康的代码。** 很多系统变复杂都是因为一点一点的小改动日积月累造成的,所以千万不要放进来任何增加复杂性的改动。 69 | 70 | ## 亮点 71 | 如果你看到变更中做的好的地方,告诉开发者他们做的很棒,尤其是当他们用某种很精巧的方式解决你评论中提到的问题时更应不吝赞美。 代码评审过多关注于错误,但你也应该为开发者展现出好的一面点赞。在指导他人的时候,有时候告诉开发者正确的做法比告诉他们错误的做法更有价值。 72 | 73 | ## 总结 74 | 75 | 在做代码评审时,你需要注意以下: 76 | 77 | - 代码设计良好。 78 | - 代码功能对用户有用。 79 | - 任何UI改动应当是深思熟虑过而且看起来不错的。 80 | - 保证线程安全。 81 | - 代码没有增加不必要的复杂性。 82 | - 开发者没有写有些将来需要但现在不知道是否需要的东西。 83 | - 代码有适当的单元测试。 84 | - 测试逻辑设计良好。 85 | - 开发者使用了清晰明了的命名。 86 | - 注释清晰明了实用,通常解释清楚了*为什么*这么做,而不是*做了啥*。 87 | - 代码又相应完善的文档。 88 | - 代码风格符合规范。 89 | 90 | 确保你review了要求你看的每一行代码,确保你正在**提升代码质量**,并且为开发者做的提升点赞。 91 | 92 | 下一篇:[代码评审的步骤](navigate.md) 93 | -------------------------------------------------------------------------------- /review/reviewer/navigate.md: -------------------------------------------------------------------------------- 1 | # 代码评审步骤 2 | 3 | 4 | ## 概要 5 | 6 | 现在你知道了[要从CL中得到什么](looking-for.md),那能在众多文件中完成评审的方法是什么? 7 | 8 | 1. 这条改动是否生效?这次变更是不是[描述](../developer/cl-descriptions.md)清晰? 9 | 2. 首先阅读CL最重要的一部分,整体上是否设计良好? 10 | 3. 按照合适的顺序阅读剩下的变更。 11 | 12 | ## 第一步: 综观这个改动 13 | 14 | 阅读[CL描述](../developer/cl-descriptions.md)并且明白CL大体内容。这些修改是否有意义?首先如果这个修改不应该有,请立刻说明为什么这些修改不应该有。当你因为这个拒绝了这次改动提交时,告诉开发人员该怎么去做是非常好的。 15 | 16 | 例如,您可能会说:“看起来您为此做了一些出色的工作,谢谢!但是,我们实际上正着手删除FooWidget系统,您正在此处进行修改,因此我们不想进行任何新的修改现在。所以,您可以重构我们的新BarWidget类吗?" 17 | 18 | 请注意,审阅者不仅拒绝了当前的CL并提供了替代建议,但他们*礼貌*地做到了。这种礼貌是重要,因为我们想表明我们甚至在开发人员之间也相互尊重,尤其是当我们意见不同时。 19 | 20 | 如果您得到的多个CL并且您不想进行的更改,您应该考虑重新设计团队的开发流程或发布的外部贡献者的流程,以便在CL完成之前进行更多的交流。最好在做大量工作之前告诉人们“不必做”,因为现在要将其丢弃或彻底重写。 21 | 22 | ## 第二步: 检查CL的主要部分 23 | 24 | 查找属于此CL的“主要”部分的文件。通常来说一个CL最重要的部分是它逻辑修改数最多的那个文件。这样有助于了解相关的CL,通常来说会加快代码评审。如果CL太大,您无法确定哪些部分是主要部分,请开发人员告诉你应该首先看什么,或要求他们[将CL拆分为多个CL](../developer/small-cls.md)。 25 | 26 | 如果您发现CL的这一部分存在一些主要的设计问题,则即使您现在没有时间审查CL的其余部分,也应立即写下这些评注。 实际上,检查其余的CL可能会浪费时间,因为如果设计问题足够严重,那么许多其他正在检查的代码将消失并且无论如何都不会发生。 27 | 28 | 立即写下这些主要设计评注非常重要有两个主要原因: 29 | 30 | - 开发人员通常会发送给审核者一个CL,然后在等待审核时立即基于该CL进行新工作。 如果您正在审查的CL中存在重大设计问题,那么他们也将不得不重新设计其以后的CL。你能在他们做太多无用功之前制止他们。 31 | - 重要的设计变更比小的变更需要更长的时间。 开发人员几乎都有截止日期;为了在截止日期之前完成工作, 并在代码库中保留高质量的代码,开发人员需要尽快开始CL的所有主要的重做。 32 | 33 | ## 第三步:依序阅读CL的其余部分 34 | 35 | 确认CL整体上没有大的设计问题后,请尝试找出逻辑顺序来浏览文件,同时还要确保不要错过对任何文件的审查。通常,在浏览了主要文件之后,按照代码审查工具向您展示它们的顺序浏览每个文件是最简单的。有时在阅读主要代码之前先阅读测试代码也是有帮助的,因为这样您就可以知道更改应该做什么。 36 | 37 | 下一节: [代码评审的速度](speed.md) 38 | -------------------------------------------------------------------------------- /review/reviewer/pushback.md: -------------------------------------------------------------------------------- 1 | # 处理代码评审中的反驳 2 | 3 | 有时开发者会在代码评审中反驳你,他们可能不同意你的意见,或者抱怨你太严格了。 4 | 5 | ## 谁是谁非? 6 | 当开发者不同意你的建议时,首先花点思考下他们是否是对的,但通常而言你比他们更熟悉代码,所以可能在某个方面理解更深。他们的争论有意义吗?从代码健康的角度来看他们的反驳有意义吗?如果是,让他们知道他们是对的,然后这个问题就解决了。 7 | 8 | 然而,开发者不总是对的,这种情况下评审者应当进一步介绍为什么他们的建议是对的。好的解释不仅得体现出对开发人员回复的理解,而且还要说明为什么要这么改。 9 | 10 | 如果评审者认为他们的建议可以改善代码质量,并且他们认为带来的代码质量改进值得开发者做这些额外的工作,评审者就应该坚持自己的立场。 11 | **不积跬步无以至千里,不积小流无以成江河** 12 | 13 | 有时候要让开发者接受,你得花很多时间反复解释,但始终确保该有的[礼貌](comments.md#courtesy),并让开发者知道你听到了他们在说什么,即便是你不同意。 14 | 15 | ## 惹恼开发者 16 | 17 | 有时评审者会认为坚持让开发者做出改动,可能会惹恼开发者。有时开发者确实会恼怒,但这种情况通常都很短暂,而且之后他们会感激你帮助他们提高了代码质量。 如果你在代码评审中很有[礼貌](comments.md#courtesy),开发者根本不会被惹恼,这种担心是多余的。通常,令惹恼开发者的是你写注解的方式,而不是你对代码质量的坚持。 18 | 19 | ## 稍后解决 20 | 21 | 一种常见的反驳原因是开发者希望能尽快完成任务。他们不想一轮又一轮地做代码评审,然后就会说他们会在后续CL中处理这些问题,你只需要通过就行。有些开发者做的很好,他们会立马提交后续CL处理这些问题。然而,经验告诉我们原始CL通过之后拖的时间越久,就越不可能修复。除非开发者在当前CL通过后*立马*修复,否则他们就不可能修复。这并不是开发者不负责任,而是因为他们有好多工作要做,而修复工作也会因为工作压力而被遗忘。所以最好坚持让开发者*现在*就在CL中处理掉这些问题,“留着以后清理”是一种不可取的方式。 22 | 23 | 如果CL中引入了新的复杂性,提交之前必须清理掉,除非是[紧急情况](../emergencies.md)。 如果CL中暴露出一些目前还无法定位的问题,开发者应该记录下这些bug,并将其分配给他们自己,确保这些问题不会被遗忘。他们还可以在代码中加入 TODO 注释,指向已经记录好的 bug。 24 | 25 | ## 抱怨太严格 26 | 27 | 如果你之前代码评审很宽容,然后突然变得严格起来,可能会引起一些开发者的抱怨。不过没关系,加快代码评审的[速度](speed.md)通常会让这些抱怨消失。 28 | 29 | 有时,这些抱怨可能需要几个月的时间才能消除,但最终开发者在看到产出的优质代码时会理解严格代码评审带来的价值。有时候,一旦发生某些事让他们真正看到严格代码评审的价值,抗议最大声的人甚至会成为你最坚定的支持者。 30 | 31 | ## 解决冲突 32 | 33 | 如果你遵循了上述方法,但仍然会在代码评审中遇到无法解决的冲突,请再次参阅[代码评审标准](standard.md),了解那些有助于解决冲突的指导和原则。 34 | 35 | -------------------------------------------------------------------------------- /review/reviewer/speed.md: -------------------------------------------------------------------------------- 1 | # 代码评审的速度 2 | 3 | ## 为什么代码评审应该快? 4 | 5 | **在谷歌内部,我们在持续优化团队开发新产品的速度**,而不是优化单个开发人员编写代码的速度。 个人开发的速度固然重要,但它没有团队整体的速度那么重要。 6 | 7 | 如果代码评审速度慢了,可能会发生以下这些事: 8 | 9 | * **整个团队的速度会降低**,是的,你不快速响应别人的代码评审也可以完成其他的工作。但是,整个团队的新功能、bug修复可能会因为没有人做cr被延迟几天、几周甚至几个月。 10 | * **开发者应维护代码评审的流程**,如果审查者很少回复代码评审,但是每次都对CL提出大量的改动,这可能会打击到开发者。通常,开发者可能会抱怨审查者太严格。如果审查者能在开发者更新后快速响应,并提出有实质性提升的建议(能显著提升代码运行状况的CL),抱怨就会消失。 **代码评审中绝大多数抱怨会随着CR速度的提升而消失。** 11 | * **可能影响到代码质量。** 如果CR慢了,可能会给开发者一种需要提交不太好代码的压力。CR慢了,也会影响到代码清理、重构、和现有CL的进一步提升。 12 | 13 | ## 应该以什么样的速度做代码评审? 14 | 15 | 如果你不是在做需要高度专注的任务,**代码评审应该越快越好** 16 | **应当在一个工作日之内**回应代码评审请求。 17 | 遵循这些指导意味着典型的CL应该在一天内进行多轮审查(如果需要)。 18 | 19 | ## 速度 vs 中断 20 | 21 | 只有一种情况下,个人的速度要胜过团队速度。**如果您正在处理诸如编写代码之类的重要工作,请不要打断自己的工作去做代码评审**,研究人在专注中被打断后需要很长的时间才能重新恢复到专注状态。所以,为了不让其他开发者等会而且中断自己的编码工作,明显得不偿失。 22 | 所以,建议你在工作断点的时候回应代码评审,比如写完代码、午饭后、会议结束后、从茶水间回来…… 23 | 24 | ## 快速响应 25 | 26 | 当我们谈论代码评审的速度时,一方面是指响应时间,另一方面是指整个Review从提交到通过的时间。整个过程应该足够快,但是对于每个人来说,迅速做出反应比迅速完成整个过程更为重要。 27 | 即使有时需要很长时间才能完成整个代码评审流程,评审者在整个过程中的快速响应也可以大大缓解开发人员因为代码评审“慢”而产生的挫败感。 28 | 如果你太忙不能全身心投入到代码评审中,你也应该让开发者知道你什么时候会去Review,或者建议其他评审者快速响应,再或者[提供一些初步的建议](navigate.md)。(注意:这不是建议你中断自己的工作,而是在工作间隙合理响应) 29 | **评审者有必要花时间去做代码评审来保证代码符合[标准](standard.md)**,不管怎么样,每个回应应当保证足够[快速](#fast)。 30 | 31 | ## 跨时区代码评审 32 | 当遇到跨时区的代码评审时,尽量在作者回家前回复。如果他们已经回家了,尽量在他们每天来公司前完成代码评审。 33 | 34 | ## LGTM和注释 35 | 36 | 为了让CR更快,有些情况下也应该让CR提前通过,即便有些评论没有被解决,比如: 37 | 38 | * 审查者信任开发者能适当解决所有评审者的建议。 39 | * 其余的改动很小,开发者不必做。 40 | 41 | 除非另有明确说明,评审者应指明他们打算使用这些选项中的哪一个。 42 | 当开发者和评审者在不同时区时,应当着重考虑下通过CR,否则开发者还得等一天。 43 | 44 | ## 大的CL 45 | 46 | 如果有人给你提交了一个非常大的代码评审,你也不确定你有时间看,你最好建议开发者[把CL拆分成几个小的部分](../developer/small-cls.md),分多次代码评审,而不是一次性全部提交上来。这即便开发者多做一些额外的工作,也是可以把它拆分开的,而且拆分也有利于评审者。 47 | 48 | 如果CL*不能*拆分成多个小CL,你也没有时间快速完整的Review整个代码,只是对整体设计提一些建议,然后发回给开发者改进。作为评审者,你的目标之一是在不牺牲代码质量的前提下,不阻碍开发者的进程或者尽可能让他们向前推进。 49 | 50 | ## 持续提升代码评审 51 | 52 | 如果你遵从这些建议并在代码评审中严格执行这些准则,你就会发现整个代码评审的流程会越来越快。 开发者将了解健康代码的要求,并从一开始就交出完美的代码,然后代码评审的时间会越来越少。评审者将学会如何快速做出响应,并且不是在这个代码评审过程中增加不必要的延迟。 53 | 但是,不要为了提升速度牺牲[代码评审的标准](standard.md)和代码质量。 从长远来看,这并不会提升速度。 54 | 55 | ## 紧急情况 56 | 57 | 当然也有一些紧急的CL需要快速走完这个代码评审流程,这时候在质量上的把控可以稍微放松一些。可以参考[紧急事件](../emergencies.md#what)一文来了解哪些是紧急事件哪些不是。 58 | 59 | 下一篇:[如何在代码评审中写评论](comments.md) 60 | 61 | -------------------------------------------------------------------------------- /review/reviewer/standard.md: -------------------------------------------------------------------------------- 1 | # 代码评审标准 2 | 3 | 代码评审的主要目的是始终保证随着时间的推移,谷歌代码越来越健康,所有代码评审的工具和流程也是针对于此设计的。 4 | 5 | 为了完成这点,我们不得不权衡利弊。 6 | 7 | 首先,开发者应当在他们代码中做一些 _改进_ ,如果你永远都不做出改进,代码库整体质量也不会提升。但是如果审查者为难所有变更,开发者未来也会失去改进的动力。 8 | 9 | 另一方面,保证代码库随时间推移越来越健康是审查者的责任,而不是让代码库质量变得越来越差。这很棘手,因为代码质量一般都会随着时间推移越来越差,尤其是在团队有明确时间限制、而且他们觉得不得不采取一些投机取巧的方式才能完成任务的情况下。 10 | 11 | 但是,代码评审者得对他们Review的代码负责,所以他们想始终确保代码库一致、可维护(其他指标见["代码评审应该关注什么?"](looking-for.md)) 12 | 13 | 依据这些,我们将以下准则作为我们期望的代码评审标准: 14 | 15 | **通常而言,只要代码对系统有明显的提升且正常工作,即便不完美,评审者也应该倾向于通过这次变更。** 16 | 17 | 这是所有代码评审指南中的高级原则。 18 | 19 | 当然这也有些局限。例如,如果变更里加入了有些评审者在系统里不想要的功能,即便代码设计的很好,评审者也可以拒绝掉。 20 | 21 | 没有完美无缺的代码,只有越来越好的代码。代码评审者绝不应该要求开发者打磨好CL中的每个细节才予以通过,相反,评审者应该权衡项目进度和他们给出建议的重要性,适当放宽要求。评审者应该追求 _持续提高_ ,而不是追求完美。那些可以提升整个系统可维护性、可读性和可以理解性的变更不应该因为代码不够完美而被推迟几天甚至几周。 22 | 23 | 评审者要 _始终_ 不拘谨于在代码评论里提示可以更好的想法。 但如果不是很重要信息,可以在评论前面加上标识告诉他们可以忽略。 24 | 25 | 注意:这篇文档中没有任何地方辩解在变更中的检查会让整个系统代码变得 _更糟糕_ 。你唯一能做的在[紧急度](../emergencies.md)中说明。 26 | 27 | ## 指导性 28 | 代码评审有个重要的作用,那就是可以教会开发者关于语言、框架或者通用软件设计原理。在代码评审中留下评论来帮助开发者学习新东西是很值得提倡的,毕竟共享知识也是长期提升系统代码健康度的一部分。但请注意,如果你的评论纯粹是教育性的,并且不是这篇文档中提到的关键标准,请在前面加上“Nit:”标识,或者明确指出不需要在这次变更中解决。 29 | 30 | ## 原则 31 | * 技术和数据高于意见和个人偏好。 32 | * 关于风格问题, [风格指南](http://google.github.io/styleguide/)是绝对的权威。任何不在样式指南中指出的样式(比如空格等)都是个人偏好的问题。风格应该与现有的一致。如果没有以前的风格,就按作者的风格来。 33 | * **软件设计从来不是纯粹的代码风格或是个人偏好问题**,它们是基于一些应当被权衡的规则而不仅仅是个人倾向。有时候也会有多种有效的选项,如果开发者能证明(通过数据或者原理)这些方法都同样有效,那么评审者应该接受作者的偏好,否则应该遵从软件设计标准。 34 | * 如果没有其他的规则使用,只要保证不会影响系统的健康度,评审者可以要求开发者保持和现有的代码库一致。 35 | 36 | ## 解决代码冲突 37 | 如果代码评审中有任何冲突,开发人员和评审人员都应该首先根据[开发者指南](../developer/)和[评审者指南](index.md)中其他文档的内容,尝试达成一致意见。 38 | 39 | 当很难达成一致时,开发者和评审者不应该在代码评审评论里解决冲突,而是应该召开面对面会议或者找个权威的人来协商。(如果你在评论里协商,确保在评论里记录了讨论结果,以便日后其他人翻阅。) 40 | 41 | 如果这样都解决不了问题,那解决问题的方式就应该升级了。通常的方式是拉着团队一起讨论、让团队主管来权衡、参考代码维护者的意见,或者让管理层来决定。**不要因为开发者和评审者不能达成一致而把变更一直放在那里。** 42 | 43 | 下一篇:[代码评审应该关注什么?](looking-for.md) 44 | --------------------------------------------------------------------------------