贡献指南

Go项目欢迎所有贡献者。

本文档旨在帮助您了解为Go项目做贡献的流程, 该流程与其他开源项目略有不同。 我们假设您已具备Git和Go语言的基础知识。

除了此处提供的信息外,Go社区还维护着一个 代码审查 Wiki页面。 您可以在学习审查流程的同时,随时向Wiki贡献内容。

请注意,gccgo 前端位于其他位置; 请参阅 为 gccgo 做贡献

成为贡献者

概述

第一步是注册成为Go贡献者并配置您的环境。 以下是需要遵循的步骤清单:

如果您愿意,有一个自动化工具可以引导您完成这些步骤。 只需运行:

$ go install golang.org/x/tools/cmd/go-contrib-init@latest
$ cd /code/to/edit
$ go-contrib-init

本章的其余部分将详细说明这些操作说明。 如果您已完成上述步骤(无论是手动操作还是通过工具),请直接跳转到 贡献代码之前

步骤 0:选择 Google 账户

对Go的贡献是通过一个具有特定电子邮件地址的Google账户进行的。 请确保在整个过程中以及所有后续贡献中使用同一账户。 您可能需要决定是使用个人地址还是公司地址。 选择将取决于您将要编写和提交的代码的版权所有者。 在决定使用哪个账户之前,您可能需要与您的雇主讨论此问题。

Google账户可以是Gmail电子邮件账户、G Suite组织账户或 与外部电子邮件地址关联的账户。 例如,如果您需要使用一个未通过G Suite管理的现有公司电子邮件, 可以创建一个与 您现有 电子邮件地址关联的账户。

您还需要确保您的Git工具配置为使用您选择的电子邮件地址创建提交。 您可以全局配置Git(作为所有项目的默认设置), 或为单个特定项目进行本地配置。 您可以使用以下命令检查当前配置:

$ git config --global user.email  # 检查当前全局配置
$ git config user.email           # 检查当前本地配置

要更改已配置的地址:

$ git config --global user.email name@example.com   # 更改全局配置
$ git config user.email name@example.com            # 更改本地配置

步骤 1:贡献者许可协议

在向Go项目提交您的第一个更改之前, 您必须完成以下两项 CLA 之一。 您应该签署哪项 CLA 取决于您工作的版权所有者是谁。

您可以在 Google 开发者 贡献者许可协议 网站上查看您当前已签署的协议并签署新协议。 如果您的贡献的版权所有者已经就另一个Google开源项目完成了该协议, 则无需再次完成。

如果您提交的代码的版权所有者发生变更—例如, 您开始代表一家新公司贡献代码—请发送邮件至 golang-dev 邮件列表。 这将使我们了解情况,以便确保完成适当的协议。

步骤 2:配置 git 身份验证

Go的主仓库位于 go.googlesource.com, 这是一个由Google托管的Git服务器。 Web服务器上的身份验证通过您的Google账户进行, 但您还需要配置计算机上的 git 才能访问它。 请按照以下步骤操作:

  1. 访问 go.googlesource.com 并点击页面右上角菜单栏中的“Generate Password”。 您将被重定向到 accounts.google.com 进行登录。
  2. 登录后,您将进入一个标题为“Configure Git”的页面。 此页面包含一个个性化脚本,在本地运行该脚本将配置 Git 以保存您唯一的身份验证密钥。 此密钥与服务器上生成并存储的密钥配对, 类似于 SSH 密钥的工作方式。
  3. 在本地终端中复制并运行此脚本,将您的秘密 身份验证令牌存储在 .gitcookies 文件中。 如果您使用的是 Windows 电脑并且正在运行 cmd, 您应转而按照黄色方框中的说明运行命令; 否则运行常规脚本。

步骤 3:创建 Gerrit 账户

Gerrit 是一个开源工具,Go 的维护者使用它来讨论和审查 代码提交。

要注册您的账户,请访问 go-review.googlesource.com/login/ 并使用您在上面使用的同一个 Google 账户登录一次。

步骤 4:安装 git-codereview 命令

对 Go 的更改在接受之前必须经过审查,无论更改由谁做出。 一个名为 git-codereview 的自定义 git 命令 简化了将更改发送到 Gerrit 的过程。

通过运行以下命令安装 git-codereview 命令:

$ go install golang.org/x/review/git-codereview@latest

确保 git-codereview 已安装在您的 shell 路径中,以便 git 命令可以找到它。 检查

$ git codereview help

输出的是帮助文本,而不是错误信息。如果它输出错误,请确保 $GOPATH/bin 已包含在您的 $PATH 中。

在 Windows 上使用 git-bash 时,您必须确保 git-codereview.exe 位于您的 git 可执行路径中。 运行 git --exec-path 以找到正确的位置,然后创建一个 符号链接,或者直接将可执行文件从 $GOPATH/bin 复制到此目录。

贡献代码之前

该项目欢迎代码补丁,但为了确保事情协调良好,您应该在开始 工作之前讨论任何重大的更改。 建议您在问题跟踪器中表明您打算贡献的意向,方式可以是 创建 一个新问题 或认领 一个 现有问题

在哪里贡献

Go 项目包括主要的 go 仓库,其中包含 Go 语言的源代码,以及许多 golang.org/x/... 仓库。 这些仓库包含了支持 Go 的各种工具和基础设施。例如,golang.org/x/pkgsite 对应 pkg.go.devgolang.org/x/playground 对应 Go 演练场,而 golang.org/x/tools 包含 各种 Go 工具,包括 Go 语言服务器 gopls。您可以在 go.googlesource.com 上看到 所有 golang.org/x/... 仓库的列表。

检查问题跟踪器

无论您已经知道要做出什么贡献,还是正在寻找 想法,问题跟踪器 始终 是首要去处。 问题会经过分类整理以归类并管理工作流。

大多数 golang.org/x/... 仓库也使用主要的 Go 问题跟踪器。然而,其中一些仓库单独管理它们的问题, 因此请务必检查您想要贡献的仓库对应的正确跟踪器。

大多数问题将标记为以下工作流标签之一:

您可以使用 GitHub 的搜索功能来寻找可以帮助解决的问题。示例:

为任何新问题开启一个 issue

除极微小的修改外,所有贡献都应关联到现有问题。 欢迎随时创建问题并讨论您的计划。 这个流程能让每个人都有机会验证设计方案, 有助于避免重复工作, 并确保该想法符合语言和工具的目标。 同时也能在代码编写前验证设计的合理性; 代码审查工具并非进行高层讨论的场所。

规划工作时请注意,Go项目主要仓库遵循六个月开发周期。 每个周期的后半段是为期三个月的功能冻结期, 期间仅接受错误修复和文档更新。 功能冻结期间仍可提交新贡献,但冻结期结束前不会合并代码。 此冻结适用于整个主仓库,以及构建发布版二进制文件所需的 golang.org/x/... 仓库中的代码。请参阅 标准库go 命令 中内嵌的包列表。

对语言、库或工具的重大修改(包括主仓库及所有 golang.org/x 仓库的API变更, 以及go 命令的命令行变更) 必须通过 变更提案流程 审核后方可接受。

敏感的安全相关问题(仅限此类问题)应报告至 security@golang.org

通过 Gerrit 提交变更

我们鼓励使用 Gerrit 提交变更进行审查。虽然对于仅使用过 GitHub 工作流的用户 存在一定的学习曲线,但这是 Go 项目贡献者使用的主要工作流, 更加流畅且功能完善。

以下章节简要介绍通过 Gerrit 提交变更的流程。 有关与 Gerrit 交互的更多详情,请参阅 Gerrit 文档。 特别建议阅读 审查界面概览 Gerrit 基础指南 — 面向 GitHub 用户页面。

概览

以下是整体流程概览:

本节后续内容将更详细地描述这些步骤。

步骤1:克隆源代码

除了需要较新版本的 Go 环境外,您还需要从正确的仓库签出源代码的本地副本。 您可以将 Go 源代码仓库克隆到本地文件系统的任意位置, 只要位于您的 GOPATH 目录外 (默认为 home 目录下的 go 目录)。 请从 go.googlesource.com(而非 GitHub)克隆:

Go 主仓库:

$ git clone https://go.googlesource.com/go
$ cd go

golang.org/x/... 仓库

(此处以 golang.org/x/tools 为例):
$ git clone https://go.googlesource.com/tools
$ cd tools

步骤2:在新分支中准备变更

每个 Go 项目的变更都必须在从主分支创建的独立分支中进行。 您可以使用常规的 git 命令来创建分支并将变更添加到暂存区:

$ git checkout -b mybranch
$ [编辑文件...]
$ git add [文件...]

提交变更时,请使用 git codereview change 而非 git commit

$ git codereview change
(打开 $EDITOR)

您可以照常在您喜欢的编辑器中编辑提交说明。 git codereview change 命令 会在底部附近自动添加一行唯一的 Change-Id。 该行用于让 Gerrit 匹配同一变更的连续上传。 请勿编辑或删除它。 Change-Id 的样子如下:

Change-Id: I2fbdbffb3aab626c4b6f56348861b7909e3e8990

该工具还会检查您是否 对源代码运行了 go fmt,以及 提交说明是否遵循 建议的格式

如果您需要再次编辑文件,可以暂存新的变更并 重新运行 git codereview change:每次后续 运行都会修改现有的提交,同时保留 Change-Id。

请确保您在每个分支中始终保持一个单独的提交。 如果误添加了 更多提交,您可以使用 git rebase将它们压缩在一起, 合并为一个提交。

步骤3:测试您的更改

您已经 编写并测试了您的代码,但 在将代码发送进行审查之前,请运行 整个代码库的所有 测试,以确保更改不会破坏其他包或程序。

在主 Go 仓库中

对于标准库包,包内的所有测试都必须通过:

$ go test

可以使用 all.bash 运行整个代码库的简短测试套件 (在 Windows 下构建请使用 all.bat):

$ cd go/src
$ ./all.bash

运行一段时间并打印大量测试输出后,该命令应以 打印以下信息结束:

ALL TESTS PASSED

您可以使用 make.bash 代替 all.bash 来仅构建编译器和标准库,而不运行测试套件。 一旦 go 工具构建完成,它将被安装到您克隆 Go 仓库目录下的 bin/go, 您可以直接从那里运行它。 另请参阅 关于如何 快速测试您的更改 的部分。

在 golang.org/x/... 仓库中

运行整个仓库的测试 (此处以 golang.org/x/tools 为例):

$ cd tools
$ go test ./...

如果您关心构建状态, 可以查看 构建状态面板。 测试失败也可能在代码审查中被 TryBots 捕获。

一些仓库,例如 golang.org/x/vscode-go,将 有不同的测试基础设施,因此请始终检查您正在工作的仓库的文档。 仓库根目录中的 README 文件通常包含此信息。

步骤4:发送更改进行审查

一旦更改准备就绪并已在整个代码库上测试完毕,即可将其发送进行审查。 这通过 mail 子命令完成,尽管其名称如此,但它并不会 直接发送邮件;它只是将更改发送到 Gerrit:

$ git codereview mail

Gerrit 会为您的更改分配一个编号和 URL,git codereview mail 会将其打印出来,类似于:

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

如果您收到错误信息,请查看 邮件错误排查 部分。

如果您的更改与一个未关闭的 GitHub issue 相关,并且您遵循了 建议的提交说明格式,那么几分钟后,一个机器人会更新该 issue, 在评论中将您的 Gerrit 更改链接到该 issue。

步骤5:根据审查修订更改

Go 维护者将在 Gerrit 上审查您的代码,您将通过电子邮件收到通知。 您可以在 Gerrit 上查看审查并在那里评论。 如果您愿意,也可以通过 使用电子邮件 进行回复。

如果您需要在审查后修订您的更改,请在您之前创建的同一分支中编辑文件,将它们添加到 Git 暂存区,然后使用 git codereview change 修改提交:

$ git codereview change     # 修改当前提交
(打开 $EDITOR)
$ git codereview mail       # 将新更改发送到 Gerrit

如果您不需要更改提交说明,只需保存并退出编辑器即可。 记住不要触碰特殊的 Change-Id 行。

再次强调,请确保您在每个分支中始终保持一个单独的提交。 如果误添加了 更多提交,您可以使用 git rebase将它们压缩在一起, 合并为一个提交。

通过 GitHub 发送更改

尽管推荐使用 Gerrit 流程且支持更好, 但已熟悉 GitHub 流程 的贡献者可以使用相同的过程进行 Go 贡献。 即使 Go 维护者使用 Gerrit 进行代码审查, 也创建了一个名为 GerritBot 的工具来同步 GitHub 拉取请求到 Gerrit。

按常规方式创建 GitHub 拉取请求即可。GerritBot 将自动创建对应的 Gerrit 变更列表(简称"CL"),并在您的 GitHub 拉取请求中发布该 CL 的链接;拉取请求的更新也会同步反映到 Gerrit CL 中。当有人在该 CL 下评论时,评论内容也会同步发布到您的拉取请求中,因此您会收到相应通知。

需要注意以下几点:

规范的提交信息

Go 项目的提交信息遵循特定的格式规范, 本节将详细说明。

以下是一个规范示例:

math: 提升超大参数下 Sin、Cos 和 Tan 函数的精度

现有实现在处理大参数时数值特性较差,
因此采用 McGillicutty 算法提升 1e10 以上计算的精度。

该算法详见 https://wikipedia.org/wiki/McGillicutty_Algorithm

Fixes #159

首行格式

变更描述的首行通常是对修改内容的简短单行摘要, 需以受影响的主要包名作为前缀。

书写要点是:应能补全句子 “此变更将 Go 修改为 ____。” 这意味着首行不应以大写字母开头,不必是完整句子, 且需准确概括变更带来的实际效果。

首行之后需空一行。

正文内容

描述正文应详细展开,需说明变更的背景和具体作用。 请使用正确的标点符号书写完整句子,如同编写 Go 代码注释。 禁止使用 HTML、Markdown 或其他标记语言。 文本建议在 72 列左右换行。 更多细节请参阅 提交信息规范

若变更影响性能,请补充相关基准测试数据。 benchstat 工具通常用于格式化变更描述中的基准测试数据。

引用 Issue

使用“Fixes #12345”格式可将变更与 Go Issue 追踪器 中的 12345 号问题关联。 当该变更被最终合入时,Issue 追踪器将自动将该问题标记为已解决。

若变更仅是解决问题过程中的阶段性进展,请改用“Updates #12345”格式。 这会在 Issue 中留下指向 Gerrit 变更的评论,但合入时不会自动关闭该问题。

若向 golang.org/x/... 仓库提交变更,必须使用 GitHub 支持的完整限定语法,确保变更关联到主仓库的 Issue(而非 x/ 仓库的 Issue)。 大多数 Issue 都在主仓库的追踪器中管理。 正确格式为“Fixes golang/go#159”。

代码审查流程

本节将详细说明审查流程及提交变更后的处理方式。

初学者常见问题

提交到 Gerrit 的变更通常在几天内会得到分类处理。 维护者会进行初步审查,对首次贡献者通常重点关注基本格式和常见问题, 主要包括:

自动化测试(Trybots)

维护者初步阅读变更后,将触发自动化测试集群。 该集群会在多种架构上运行完整测试套件。 大多数测试在几分钟内完成,结果链接将发布在 Gerrit 页面中供查看。

如果自动化测试(trybot)运行失败,请点击链接查看测试失败平台的完整日志。 分析失败原因,更新补丁进行修复后重新上传。 维护者将触发新一轮自动化测试,以确认问题是否已解决。

有时,某些平台的代码库可能出现数小时的构建问题。若自动化测试报告的错误似乎与您的补丁无关,请访问 构建状态面板,检查同一平台的其他近期提交是否出现相同错误。 此时,您可在 Gerrit 中留言说明该错误与您的变更无关,以协助维护者理解情况。 也可在 GitHub 问题中搜索错误信息,或浏览近期更新的 watchflakes 问题列表。 若您的变更基于较早的提交,或怀疑问题可能已被他人修复,可通过 git rebase 命令变基至最新的主分支提交。

代码审查

Go 社区推崇严谨细致的代码审查。 请将每条审查意见视同待办工单:您需要通过实际修改或说服审查者来 "关闭"该工单。

更新变更后,请逐条回复所有审查意见。 您可点击"完成"按钮表示已采纳审查者建议;若未采纳,请点击"回复"说明原因或具体替代方案。

变更经历多轮审查是正常现象,审查者每次都会提出新意见并等待更新后再进行复审。 即使是经验丰富的贡献者也会经历这个过程,请勿因此气馁。

投票规范

临近决策时,审查者将为您的变更进行代码审查"投票"。投票结果分为两种:

变更必须获得维护者的代码审查 +2 票方可提交。

维护者还可对变更投出"保留 +1"票,标记暂不可提交的变更 (例如,变更中新增 API 的提案评审尚未完成)。

变更不能存在任何维护者投出的"保留 +1"票方可提交。

最终提交前,变更必须涉及两名谷歌员工:可作为变更上传者,或作为审查者至少投出代码审查 +1 票。此要求是出于合规性及供应链安全考量。

提交已批准的变更

当变更准备就绪时,维护者将提交变更,使其作为新提交记录纳入 Gerrit 代码库。

批准与提交是两个独立步骤,因为维护者有时可能批准变更但暂不提交(例如代码库处于临时冻结期)。

提交操作会将变更检入代码库。变更描述中将包含代码审查链接,该链接会更新为指向代码库中的变更记录。 由于采用 Git 的"精选提交"方式集成变更,提交操作会改变代码库中的提交哈希值。

若您的变更已获批数日仍未提交,可在 Gerrit 中留言提醒提交。

更多信息

除本文档外,Go 社区还维护着代码审查维基页面。随着您对审查流程的深入了解,欢迎为此页面贡献内容。

其他专题

本节汇集了问题跟踪/编辑/代码审查/提交流程之外的补充说明。

Gopls

在主 Go 代码库工作且编辑器使用 gopls 时,gopls 调用的 go 命令版本需与您正在处理的源代码版本一致。 可使用 make.bash 构建 go 命令,并将生成的 bin 目录添加至系统 PATH 环境变量。 详见Gopls:高级主题

Gopls 完整文档详见 https://go.dev/gopls。

Go 代码库中的文件不列出作者姓名,以避免内容冗余并保持信息时效性。 您的姓名将出现在变更日志中。

您贡献的新文件应使用标准版权标头:

// Copyright 2026 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.

代码库中文件的版权年份为其添加年份。请勿更新您修改的文件的版权年份。

邮件错误排查

git codereview mail 命令失败的最常见原因是:提交中的电子邮件地址与注册流程中使用的地址不一致。
如果你看到类似以下内容...

remote: Processing changes: refs: 1, done
remote:
remote: ERROR:  In commit ab13517fa29487dcf8b0d48916c51639426c5ee9
remote: ERROR:  author email address XXXXXXXXXXXXXXXXXXX
remote: ERROR:  does not match your user account.

你需要为此仓库配置 Git,使其使用你注册时使用的电子邮件地址。 要更改电子邮件地址以确保此情况不再发生,请运行:

$ git config user.email email@address.com

然后使用以下命令更改提交以使用此替代电子邮件地址:

$ git commit --amend --author="Author Name <email@address.com>"

然后通过运行以下命令重试:

$ git codereview mail

快速测试你的更改

每次更改代码树时都运行 all.bash 是很繁琐的。 虽然强烈建议在发送更改前运行它,但在正常的开发周期中,你可能只想编译和测试你正在开发的包。

指定审查者 / 抄送他人

除非另有明确说明(例如在发送更改前的讨论中), 最好不要指定审查者。 所有更改都会自动抄送到 golang-codereviews@googlegroups.com 邮件列表。 如果这是你的首次更改,为了防止垃圾邮件,它在邮件列表上出现之前可能会有审核延迟。

你可以使用 -r-cc 选项指定审查者或抄送相关方。 两者都接受逗号分隔的电子邮件地址列表:

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

同步你的客户端

当你正在工作时,其他人可能已向仓库提交了更改。 要更新你的本地分支,请运行

$ git codereview sync

(这实际上运行的是 git pull -r。)

审查他人的代码

作为审查过程的一部分,审查者可以直接提出更改(在 GitHub 工作流中, 这可能是其他人将提交附加到拉取请求)。 Gerrit 提供了访问命令的方式,这些命令可以帮助你导入其他开发者提议的更改, 以便你可以在本地进行审查/测试。从你要导入的 CL 的 Gerrit 页面, 打开"⋮"菜单,点击"Download patch"链接。 根据你偏好的 git 工作流,选择合适的命令。选项看起来类似这样:

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

要撤消,请切换回你之前正在工作的分支。

设置 git 别名

git-codereview 命令可以直接从 shell 运行, 例如通过输入,

$ git codereview sync

但为 git-codereview 自身的子命令设置别名会更方便, 这样上面的命令就可以变为,

$ git sync

git-codereview 的子命令特意设计得与 Git 原生命令不同,因此设置这些别名是安全的。 要安装它们,请将以下文本复制到你的 Git 配置文件(通常是你主目录下的 .gitconfig 文件)中:

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

发送多个关联的变更

高级用户可能希望将相关的提交堆叠在同一个分支中。Gerrit 允许变更相互依赖,形成这样的依赖链。每个变更都需要分别审批和提交,但依赖关系对审查者是可见的。

要发送一组关联的变更,请将每个变更作为不同的提交保存在同一个分支下,然后运行:

$ git codereview mail HEAD

请务必显式指定 HEAD,这在发送单个变更时通常是不需要的。更多详情请参阅 git-codereview 文档

次要版本

如果你想对发布分支进行更改以进行向后移植,请参阅 次要版本