...

贡献指南

Introduction

引言

This document explains how to contribute changes to the Go project. It assumes you have followed the installation instructions and have written and tested your code.

本文档说明了如何向 Go 项目贡献更改。假设你已经按照 安装说明 安装了Go,且已经 编写并测试了你的代码

(Note that the gccgo frontend lives elsewhere; see Contributing to gccgo.)

(关于 gccgo 前端的文档见为 gccgo 做贡献。)

Discuss your design

讨论你的设计

The project welcomes submissions but please let everyone know what you're working on if you want it to become part of the main repository.

本项目欢迎提交意见,但若想让它成为主源码库的一部分,请让所有人都知道你所做的事。

Before undertaking to write something new for the Go project, send mail to the mailing list to discuss what you plan to do. This gives everyone a chance to validate the design, helps prevent duplication of effort, and ensures that the idea fits inside the goals for the language and tools. It also guarantees that the design is sound before code is written; the code review tool is not the place for high-level discussions.

在着手为 Go 项目编写新代码前,请先向 邮件列表 发送邮件来讨论你的计划。这能让所有人都确认你的设计,帮助避免重复劳动, 并确认此想法是否符合该语言或工具的目标。此外,这也能在编写代码前保证该设计经过了充分的考虑; 代码审核工具并不是进行高级讨论的地方。

In short, send mail before you code. And don't start the discussion by mailing a change list!

简言之,写代码前请先发邮件,不要通过发送更改列表来开始讨论!

Testing redux

最终测试

You've written and tested your code, but before sending code out for review, run all the tests for the whole tree to make sure the changes don't break other packages or programs:

若你已经 编写并测试了你的代码, 在发送代码接受审核前,还需要对整个代码树运行所有的测试,以确保此更改不会破坏其它包或程序:

$ cd go/src
$ ./all.bash

(To build under Windows use all.bat.)

(在 Windows 下,请运行 all.bat。)

After running for a while, the command should print "ALL TESTS PASSED".

在运行一会儿之后,命令行应当打印出 "ALL TESTS PASSED".

Code review

代码审核

Changes to Go must be reviewed before they are accepted, no matter who makes the change. A custom git command called git-codereview, discussed below, helps manage the code review process through a Google-hosted instance of the code review system called Gerrit.

无论谁对 Go 进行更改,在它被递交前都必须进行审核(在特殊情况下,比如修复一个构建,可在递交后进行审核)。 稍后我们会讨论名为 git-codereview 的定制 git 命令,它能通过 Gerrit 代码审核系统的 Google 托管的 实例 来帮助管理代码审核流程。

Set up authentication for code review

设置代码审核认证

Gerrit uses Google Accounts for authentication. If you don't have a Google Account, you can create an account which includes a new Gmail email account or create an account associated with your existing email address.

Git 代码托管服务器和 Gerrit 代码审核服务器都通过 Google 账户来认证,因此你需要一个 Google 账户来继续(就是说只要你能用一个账户登录到 google.com, 那么就能用它来登录到代码审核服务器)。你在代码审核系统上使用的邮件地址会被记录在 更改记录CONTRIBUTORS 文件中。 你可以用任何可接收邮件的地址来创建一个 Google 账户

The email address associated with the Google Account you use will be recorded in the change log and in the contributors file.

与你的 Google 账户关联的邮件地址将被记录在 更改日志贡献者文件 中。

To set up your account in Gerrit, visit go.googlesource.com and click on "Generate Password" in the page's top right menu bar.

要在 Gerrit 上设置你的账户,请访问 go.googlesource.com 并通点击页面右上角菜单中的“Generate Password”(生成密码)。

You will be redirected to accounts.google.com to sign in.

你会被重定向至 accounts.google.com 进行登录。

Once signed in, you are returned back to go.googlesource.com to "Configure Git". Follow the instructions on the page. (If you are on a Windows computer, you should instead follow the instructions in the yellow box to run the command.)

一旦登录成功,你就会返回到 go.googlesource.com 来“设置 Git”(Configure Git), 请遵循该页面的指示进行设置。(若你在 Windows 系统上,请按照黄色文本框内的指示来运行命令。)

Your secret authentication token is now in a .gitcookie file and Git is configured to use this file.

现在你的私人认证令牌会存储在 .gitcookie 文件中,Git 会被设置为使用该文件。

Register with Gerrit

注册 Gerrit

Now that you have your authentication token, you need to register your account with Gerrit. To do this, visit go-review.googlesource.com/login/. You will immediately be redirected to Google Accounts. Sign in using the same Google Account you used above. That is all that is required.

现在你已经有了 Google 账户和认证标记,还需要在 Gerrit 代码审核系统上注册你的账户。 请访问 golang.org/cl 并使用前面的 Google 账户登录, 这样就设置完成了。

Install the git-codereview command

安装 git-codereview 命令

Now install the git-codereview command by running,

现在安装 git-codereview 命令。运行

$ go get -u golang.org/x/review/git-codereview

Make sure git-codereview is installed in your shell path, so that the git command can find it. Check that

请确保 git-codereview 安装到了你的 shell 路径中,这样 git 命令就能找到它了。请运行

$ git codereview help

prints help text, not an error.

来检查,应该会打印出帮助文本而非错误。

Note to Git aficionados: The git-codereview command is not required to upload and manage Gerrit code reviews. For those who prefer plain Git, the text below gives the Git equivalent of each git-codereview command. If you do use plain Git, note that you still need the commit hooks that the git-codereview command configures; those hooks add a Gerrit Change-Id line to the commit message and check that all Go source files have been formatted with gofmt. Even if you intend to use plain Git for daily work, install the hooks in a new Git checkout by running git-codereview hooks.

Git 迷请注意:git-codereview 对于上传并管理 Gerrit 代码审核来说并不是必须的。 对于喜欢纯 Git 的人来说,下面的方法可以让 Git 等价于每个 git-codereview 命令。若你使用纯 Git,那么你仍需要 git-codereview 命令来设置提交钩子(hook),这些钩子会在提交信息中添加一行 Gerrit Change-Id,并检查所有的 Go 源文件是否已被 gofmt 格式化。 即便你想要在日常工作中使用纯 Git,也需要在新的 Git 检出中运行 git-codereview hooks 来安装这些钩子。

Set up git aliases

设置 Git 别名

The git-codereview command can be run directly from the shell by typing, for instance,

git-codereview 命令可直接在 shell 中输入运行。例如

$ git codereview sync

but it is more convenient to set up aliases for git-codereview's own subcommands, so that the above becomes,

不过为 git-codereview 的子命令设置别名会更加方便,这样上面的命令就变成了

$ git sync

The git-codereview subcommands have been chosen to be distinct from Git's own, so it's safe to do so.

git-codereview 的子命令与 Git 自己的不同,所以这么做很安全。

The aliases are optional, but in the rest of this document we will assume they are installed. To install them, copy this text into your Git configuration file (usually .gitconfig in your home directory):

这些别名是可选的,不过之后本文档会假定你已经安装了它们。要设置这些别名,请将以下文本复制到你的 Git 配置文件中(一般为你的 home 目录中的 .gitconfig 文件):

[alias]
	change = codereview change
	gofmt = codereview gofmt
	mail = codereview mail
	pending = codereview pending
	submit = codereview submit
	sync = codereview sync

Understanding the git-codereview command

了解 git-codereview 命令

After installing the git-codereview command, you can run

在安装好 git-codereview 命令后,你可以运行

$ git codereview help

to learn more about its commands. You can also read the command documentation.

来了解此命令的更多详情。你也可以阅读它的 命令文档

Switch to the master branch

切换到 master 分支

Most Go installations use a release branch, but new changes should only be made based on the master branch. (They may be applied later to a release branch as part of the release process, but most contributors won't do this themselves.) Before making a change, make sure you start on the master branch:

大部分 Go 安装会使用发行(release)分支,但新的更改应当只在 master 分支上进行。 (之后它们或许会被作为发行流程的一部分应用到某个发行分支,不过大部分贡献者不会自己做这件事。) 在进行更改前,请确保你处在 master 分支上:

$ git checkout master
$ git sync

(In Git terms, git sync runs git pull -r.)

(按照 Git 术语,git sync 会运行 git pull -r。)

Make a change

进行更改

The entire checked-out tree is writable. Once you have edited files, you must tell Git that they have been modified. You must also tell Git about any files that are added, removed, or renamed files. These operations are done with the usual Git commands, git add, git rm, and git mv.

整个检出的树都是可写的。在你编辑过文件后,必须要告诉 Git 它们已被修改。你还必须告诉 Git 哪些文件已被添加,移除或重命名。这些操作可分别用一般的 Git 命令 git addgit rmgit mv 来完成。

If you wish to checkpoint your work, or are ready to send the code out for review, run

若你想要检查自己的工作,或已准备好发送代码以备审核,请在你想要提交更改的 Go 源码库中运行

$ git change <branch>

from any directory in your Go repository to commit the changes so far. The name <branch> is an arbitrary one you choose to identify the local branch containing your changes.

这里的 <branch> 是由你命名的本地分支,你需要选择它的名字来标示出你所进行的更改。

(In Git terms, git change <branch> runs git checkout -b branch, then git branch --set-upstream-to origin/master, then git commit.)

(按照 Git 术语,git change <branch> 会依次运行 git checkout -b branchgit branch --set-upstream-to origin/mastergit commit。)

Git will open a change description file in your editor. (It uses the editor named by the $EDITOR environment variable, vi by default.) The file will look like:

Git 会在你的编辑器中打开一份更改描述文件。 (它会使用 $EDITOR 环境变量指定的编辑器,默认为 vi。) 该文件看起来就像这样:


# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch foo
# Changes not staged for commit:
#	modified:   editedfile.go
#

At the beginning of this file is a blank line; replace it with a thorough description of your change. The first line of the change description is conventionally a one-line summary of the change, prefixed by the primary affected package, and is used as the subject for code review mail. The rest of the description elaborates and should provide context for the change and explain what it does. If there is a helpful reference, mention it here.

本文件开头为一行空行,请在此对你的更改进行全面的描述。按照约定,该描述的第一行为单行的更改摘要, 前缀主要影响的包,它将作为代码审核邮件的主题。剩下的描述需阐明此更改并提供上下文,以及解释它做了什么。 若有相关的帮助引用,请在此提及。

After editing, the template might now read:

在编辑之后,该模版会类似于这样:

math: improved Sin, Cos and Tan precision for very large arguments

The existing implementation has poor numerical properties for
large arguments, so use the McGillicutty algorithm to improve
accuracy above 1e10.

The algorithm is described at http://wikipedia.org/wiki/McGillicutty_Algorithm

Fixes #159

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch foo
# Changes not staged for commit:
#	modified:   editedfile.go
#

The commented section of the file lists all the modified files in your client. It is best to keep unrelated changes in different change lists, so if you see a file listed that should not be included, abort the command and move that file to a different branch.

本文件中的注释一节会列出你在本地修改过的所有文件。我们最好将无关的更改放到不同的更改列表中, 因此若你看到列表中出现了不应包含的文件,请中断此命令,并将该文件移动到不同的分支中。

The special notation "Fixes #159" associates the change with issue 159 in the Go issue tracker. When this change is eventually submitted, the issue tracker will automatically mark the issue as fixed. (There are several such conventions, described in detail in the GitHub Issue Tracker documentation.)

特殊的标记“Fixes issue 159.”会将此更改关联到 Go 问题跟踪器 中的第159号问题。当此更改最终被递交后,问题跟踪器会自动将该问题标记为已修复。 (还有几个类似的约定,在 GitHub 问题跟踪器文档 中有详细的描述。)

Once you have finished writing the commit message, save the file and exit the editor.

写完提交信息后,请保存文件并退出编辑器。

If you wish to do more editing, re-stage your changes using git add, and then run

若你想要进行更多编辑,请用 git add 命令再次暂存你的更改,然后运行

$ git change

to update the change description and incorporate the staged changes. The change description contains a Change-Id line near the bottom, added by a Git commit hook during the initial git change. That line is used by Gerrit to match successive uploads of the same change. Do not edit or delete it.

来更新更改描述并加入暂存的更改。Git 提交钩子会在初始执行 git change 时在更改描述的底部加入一行 Change-Id,以便让 Gerrit 跟踪同一更改的后续上传。 请勿编辑或删除它。

(In Git terms, git change with no branch name runs git commit --amend.)

(按照 Git 术语,不带分支名的 git change 会运行 git commit --amend。)

Mail the change for review

为审核邮寄更改

Once the change is ready, mail it out for review:

一旦更改就绪,请邮寄它已备审核:

$ git mail

You can specify a reviewer or CC interested parties using the -r or -cc options. Both accept a comma-separated list of email addresses:

你可以通过 -r-cc 选项来指定审核者或抄送给对它感兴趣的同伴。 两个命令都接受逗号分隔的邮件地址列表:

$ git mail -r joe@golang.org -cc mabel@example.com,math-nuts@swtch.com

Unless explicitly told otherwise, such as in the discussion leading up to sending in the change list, it's better not to specify a reviewer. All changes are automatically CC'ed to the golang-codereviews@googlegroups.com mailing list.

除非被明确告知,例如在讨论中需要接收此更改列表的人,否则最好不要指定审核者。所有更改都会自动抄送至 golang-codereviews@googlegroups.com 邮件列表。

(In Git terms, git mail pushes the local committed changes to Gerrit using git push origin HEAD:refs/for/master.)

(按照 Git 术语,git mail 会通过 git push origin HEAD:refs/for/master 来将本地提交的更改推送到 Gerrit。)

If your change relates to an open issue, please add a comment to the issue announcing your proposed fix, including a link to your CL.

若你的更改涉及到一个开放问题,请为该问题添加一条评论宣布你提议的修复,其中包括你的CL(更改列表)链接。

The code review server assigns your change an issue number and URL, which git mail will print, something like:

代码审核服务器会为你的更改分配一个问题编号和URL,git mail 会打印出它,类似于:

remote: New Changes:
remote:   https://go-review.googlesource.com/99999 math: improved Sin, Cos and Tan precision for very large arguments

Reviewing code

审核代码

Running git mail will send an email to you and the reviewers asking them to visit the issue's URL and make comments on the change. When done, the reviewer adds comments through the Gerrit user interface and clicks "Reply" to send comments back. You will receive a mail notification when this happens. You must reply through the web interface. (Unlike with the old Rietveld review system, replying by mail has no effect.)

运行 git mail 会向你和审核者发送一封邮件, 要求他们访问该问题的URL并对该更改进行评论。之后,审核者会通过 Gerrit 用户界面添加怕你概论并点击 “Reply”(回复)来发送评论,此时你会收到一封邮件提醒。你必须通过Web界面来回复。 (不像旧的 Rietveld 审核系统,直接通过邮件回复不会有任何效果。)

Revise and upload

修订并上传

You must respond to review comments through the web interface. (Unlike with the old Rietveld review system, responding by mail has no effect.)

你必须通过Web界面来回应审核评论。 (不像旧的 Rietveld 审核系统,直接通过邮件回应不会有任何效果。)

When you have revised the code and are ready for another round of review, stage those changes and use git change to update the commit. To send the update change list for another round of review, run git mail again.

当你修订过代码并准备进行下一轮审核时,请暂存那些更改并通过 git change 来更新提交。要为下一轮审核发送更新后的更改列表,请再次运行 git mail

The reviewer can comment on the new copy, and the process repeats. The reviewer approves the change by giving it a positive score (+1 or +2) and replying LGTM: looks good to me.

审核者会对新的副本进行评论,此过程继续重复。若审核者者接受了此更改,就会给它加分(+1或+2)并回复 LGTM:looks good to me(我很满意)。

You can see a list of your pending changes by running git pending, and switch between change branches with git change <branch>.

你可以通过运行 git pending 来查看待定的更改,运行 git change <branch> 可以切换更改分支。

Synchronize your client

同步客户端

While you were working, others might have submitted changes to the repository. To update your local branch, run

在你工作期间,其他人可能已经向源码库递交了更改。要更新你的本地分支,请运行

$ git sync

(In git terms, git sync runs git pull -r.)

(按照 Git 术语,git sync 会运行 git pull -r。)

If files you were editing have changed, Git does its best to merge the remote changes into your local changes. It may leave some files to merge by hand.

若你编辑的文件已被更改,Git 会尽力将远程修改合并到你的本地分支更改中。 它也可能会留下一些需要手动合并的文件。

For example, suppose you have edited sin.go but someone else has committed an independent change. When you run git sync, you will get the (scary-looking) output:

例如,假设你编辑了 sin.go,但某人又提交了一个独立的更改。 当你在运行 git sync 时,会看到略吓人的输出:

$ git sync
Failed to merge in the changes.
Patch failed at 0023 math: improved Sin, Cos and Tan precision for very large arguments
The copy of the patch that failed is found in:
   /home/you/repo/.git/rebase-apply/patch

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

If this happens, run

若发生了这种情况,请运行

$ git status

to see which files failed to merge. The output will look something like this:

来查看哪些文件合并失败了。输出看起来会像这样:

rebase in progress; onto a24c3eb
You are currently rebasing branch 'mcgillicutty' on 'a24c3eb'.
  (fix conflicts and then run "git rebase --continue")
  (use "git rebase --skip" to skip this patch)
  (use "git rebase --abort" to check out the original branch)

Unmerged paths:
  (use "git reset HEAD <file>..." to unstage)
  (use "git add <file>..." to mark resolution)

	both modified: sin.go

The only important part in that transcript is the italicized "both modified" line: Git failed to merge your changes with the conflicting change. When this happens, Git leaves both sets of edits in the file, with conflicts marked by <<<<<<< and >>>>>>>. It is now your job to edit the file to combine them. Continuing the example, searching for those strings in sin.go might turn up:

这些记录中唯一重要的部分就是斜体的“both modified”行:Git 在将你的更改和冲突的更改合并时失败了。 在发生这种情况时,Git 会在该文件中保留两种编辑版本,并用冲突标记 <<<<<<<>>>>>>> 标出。现在你需要编辑该文件来合并它们。 继续这个例子,在 sin.go 中搜索这些标记会找到:

	arg = scale(arg)
<<<<<<< HEAD
	if arg < 1e9 {
=======
	if arg &lh; 1e10 {
>>>>>>> mcgillicutty
		largeReduce(arg)

Git doesn't show it, but suppose the original text that both edits started with was 1e8; you changed it to 1e10 and the other change to 1e9, so the correct answer might now be 1e10. First, edit the section to remove the markers and leave the correct code:

Git 不会显示它,不过假设二者编辑前的原始的文本为 1e8,你把它改成了 1e10 而另一个人把它改成了 1e9,所以正确的答案或许为 1e10。首先,编辑这一小节来移除冲突标记并保留正确的代码:

	arg = scale(arg)
	if arg < 1e10 {
		largeReduce(arg)

Then tell Git that the conflict is resolved by running

然后运行以下命令告诉 Git 该冲突已被解决

$ git add sin.go

If you had been editing the file, say for debugging, but do not care to preserve your changes, you can run git reset HEAD sin.go to abandon your changes. Then run git rebase --continue to restore the change commit.

若你已经编辑了该文件(比如说为了调试),但并不想保留你的更改,那么可以运行 git reset HEAD sin.go 来丢弃你的更改。接着运行 git rebase --continue 来恢复更改提交。

Reviewing code by others

由他人审核

You can import a change proposed by someone else into your local Git repository. On the Gerrit review page, click the "Download ▼" link in the upper right corner, copy the "Checkout" command and run it from your local Git repo. It should look something like this:

你可以将他人提议的更改导入到自己本地的 Git 源码库中。在 Geriit 审核页面中,点击右上角的 “Download ▼” 链接,复制“Checkout”命令并在你的本地 Git 源码库中运行它。它看起来类似于:

$ git fetch https://go.googlesource.com/review refs/changes/21/1221/1 && git checkout FETCH_HEAD

To revert, change back to the branch you were working in.

要恢复,只需切换回你工作的分支即可。

Submit the change after the review

审核后递交更改

After the code has been LGTM'ed, an approver may submit it to the master branch using the Gerrit UI. There is a "Submit" button on the web page for the change that appears once the change is approved (marked +2).

在代码被标为 LGTM 后,批准人可能会通过 Gerrit 界面将它递交到 master 分支。 一旦该更改通过后(标记为+2),其Web页面上就会出现“Submit”(递交)按钮。

This checks the change into the repository. The change description will include a link to the code review, and the code review will be updated with a link to the change in the repository. Since the method used to integrate the changes is "Cherry Pick", the commit hashes in the repository will be changed by the submit operation.

这会将该更改签入到源码库中。 更改记录会包含此代码审核页面的链接,而该页面则会被添加上此更改在源码库中的链接。 由于用来集成此更改的方法是“Cherry Pick”,因此源码库中的提交校验值(hash)会被递交操作更改。

More information

更多信息

In addition to the information here, the Go community maintains a CodeReview wiki page. Feel free to contribute to this page as you learn the review process.

除了这里的信息,Go 社区还维护了一份 CodeReview 维基页面。请随意向此页面贡献你所了解的审核流程。

版权

Files in the Go repository don't list author names, both to avoid clutter and to avoid having to keep the lists up to date. Instead, your name will appear in the change log and in the CONTRIBUTORS file and perhaps the AUTHORS file.

Go 源码库中的文件不会列出作者的名字,这样既能避免混乱,又能避免时刻保持列表更新。 取而代之,你的名字会出现在更改记录CONTRIBUTORS 文件内,也可能出现在 AUTHORS 文件中。

The CONTRIBUTORS file defines who the Go contributors—the people—are; the AUTHORS file defines who “The Go Authors”—the copyright holders—are. The Go developers at Google will update these files when submitting your first change. In order for them to do that, you need to have completed one of the contributor license agreements:

CONTRIBUTORS 文件定义了谁是 Go 的贡献者, 即个人贡献者;AUTHORS 文件定义了谁是版权拥有者, 即“Go 的作者”。Google 的 Go 开发者会在递交你的第一个更改时更新这些文件。 为此,你必须完成贡献者许可协议之一:

  • If you are the copyright holder, you will need to agree to the individual contributor license agreement, which can be completed online.
  • If your organization is the copyright holder, the organization will need to agree to the corporate contributor license agreement. (If the copyright holder for your code has already completed the agreement in connection with another Google open source project, it does not need to be completed again.)

This rigmarole needs to be done only for your first submission.

这些琐事只需在你第一次递交时完成。

Code that you contribute should use the standard copyright header:

你贡献的代码应使用标准的版权文件头:

// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

Files in the repository are copyright the year they are added. It is not necessary to update the copyright year on files that you change.

源码库中的文件其版权年份即为它被添加的年份。你在更改这些文件时,无需更新版权年份。