【譯】Go 語言原始碼貢獻官方指導文件
以前給 Go 語言專案原始碼提交過一些 commits,期間閱讀他們的官方指導文件的時候覺得這篇指導文件可以作為絕佳的關於大型軟體專案的規範管理的參考,因為最近又提交了幾個 commits,就又把這篇文件再看了一遍,有感於 Go 團隊在專案管理和工程實踐上的一些寶貴經驗,就把文件翻譯成了中文;一來為了更加深入地理解 Go 語言團隊的專案工程最佳實踐,二來則是為了給其他有意給 Go 語言原始碼提交貢獻的開發者提供一點參考。
Go 語言專案歡迎所有程式碼貢獻者。
這是一份指導你完成向 Go 語言專案貢獻程式碼整個流程的文件,會略微跟其他開源專案所使用的指導文件有所不同。我們假設閱讀者已經對 Git 和 Go 有基本的理解以及具備相關的基礎知識。
除了這裡所介紹的資訊,Go 語言社群也維護了一份關於程式碼評審的 wiki 頁面。在你學習 review 的過程中,歡迎隨時給這份 wiki 貢獻、補充新內容。
請注意, gccgo
前端的文件在另一處;看這裡:Contributing to gccgo。
成為一個程式碼貢獻者
概述
第一步需要註冊成為一個 Go contributor 以及配置你的環境。這裡有一份包含了所需步驟的清單:
- 步驟 0: 準備好一個你將用來給 Go 語言貢獻程式碼的 Google 賬號。在後面所有的步驟中都要使用這個賬號,還有確保你的
git
已經正確配置了這個賬號的郵箱地址,以便後續提交 commits。 - 步驟 1: 簽署以及提交一個 CLA(貢獻者證書協議)。
- 步驟 2: 給 Go Git 倉庫配置好許可權憑證。訪問 go.googlesource.com,點選右上角的齒輪圖示,接著點選 "Obtain password",然後跟著指引操作即可。
- 步驟 3: 在這個頁面註冊一個 Gerrit 賬號,它是 Go 語言團隊使用的程式碼評審工具。CLA 的申請和 Gerrit 的註冊只需要在你的賬號上做一次就可以了
- 步驟 4: 執行
go get -u golang.org/x/review/git-codereview
命令安裝git-codereview
工具。
如果你圖省事的話,可以直接用自動化工具幫你做完上面的全部步驟,只需執行:
$ go get -u golang.org/x/tools/cmd/go-contrib-init
$ cd /code/to/edit
$ go-contrib-init
這個章節的後面部分將會更加詳盡地闡述上面的每一個步驟。如果你已經完成上面的所有步驟(不管是手動還是通過自動化工具),可以直接跳到貢獻程式碼之前部分。
步驟 0: 選擇一個 Google 賬號
每一個提交到 Go 語言的程式碼貢獻都是通過一個繫結了特定郵箱地址的 Google 賬號來完成的。請確保你在整個流程中自始至終使用的都是同一個賬號,當然,後續你提交的所有程式碼貢獻也是如此。你可能需要想好使用哪一種郵箱,個人的還是企業的。郵箱型別的選擇將決定誰擁有你編寫和提交的程式碼的版權。在決定使用哪個賬戶之前,你大概要和你的僱主商議一下。
Google 賬號可以是 Gmail 郵箱賬號、G Suite 組織賬號,或者是那些繫結了外部郵箱的賬號。例如,如果你想要使用一個已存在且並不屬於 G Suite 的企業郵箱,你可以建立一個繫結了外部郵箱的 Google 賬號。
你還需要確保你的 Git 工具已經正確配置好你之前選定的郵箱地址,用來提交程式碼。你可以通過 Git 命令來進行全域性配置 (所有專案都將預設使用這個配置) 或者只進行本地配置 (只指定某個特定的專案使用)。可以通過以下的命令來檢查當前的配置情況:
$ git config --global user.email # check current global config
$ git config user.email # check current local config
修改配置好的郵箱地址:
$ git config --global user.email name@example.com # change global config
$ git config user.email name@example.com # change local config
步驟 1: 貢獻者證書協議
在你提交第一個程式碼變更到 Go 語言專案之前,你必須先簽署下面兩種證書協議的其中之一。最後的程式碼版權歸屬於誰,將決定你應該簽署哪一種協議。
- 如果你個人是版權持有方,你就需要同意 individual contributor license agreement 並簽署,這個步驟可以線上上完成。
- 如果企業/組織是版權持有方,那麼企業/組織就需要同意 corporate contributor license agreement 並簽署。
你可以在 Google Developers Contributor License Agreements 網站上檢查當前已簽署的協議以及再簽署新的協議。如果你程式碼的版權持有方之前已經在其他的 Google 開源專案上籤署過這些協議了,那麼就不需要再重複簽署了。
如果你程式碼的版權持有方更改了--例如,如果你開始代表新的公司來貢獻程式碼--請傳送郵件到 golang-dev
郵件組。這樣我們可以知悉情況,接著準備一份新的協議檔案以及更新 作者
檔案。
步驟 2: 配置 Git 認證資訊
Go 語言的主倉庫位於 go.googlesource.com,這是一個 Google 自建的 Git 伺服器。Web 伺服器上的認證資訊是通過你的 Google 帳戶生成的,不過你還是需要在你的個人電腦上安裝配置 git
來訪問它。按照以下的步驟進行:
- 訪問 go.googlesource.com 然後點選頁面右上角選單條上的 "Generate Password" 按鈕。接著你會被重定向到
accounts.google.com
去登陸。 - 登陸之後,你會被引導到一個標題為 "Configure Git" 的網頁。這個網頁包含了一段個性化的指令碼程式碼,執行這個指令碼之後會自動生成身份認證的金鑰並配置到 Git 裡面去。這個金鑰是和另一個在遠端 Server 生成並儲存的金鑰成對的,類似於 SSH 金鑰對的工作原理。
- 複製這段指令碼並在你的個人電腦上的終端執行一下,你的金鑰認證 token 就會被儲存到一個
.gitcookies
的檔案裡。如果你使用的是 Windows 電腦,那你應該複製並執行黃色方格里的指令碼,而不是下面那個通用的指令碼。
步驟 3: 建立一個 Gerrit 賬號
Gerrit 是 Go 語言團隊所使用的一個開源工具,用來進行討論和程式碼評審。
要註冊一個你自己的 Gerrit 賬號,訪問 go-review.googlesource.com/login/ 然後使用你上面的 Google 賬號登陸一次,然後就自動註冊成功了。
步驟 4: 安裝 git-codereview 命令列工具
無論是誰,提交到 Go 語言原始碼的程式碼變更在被接受合併之前,必須要經過程式碼評審。Go 官方提供了一個叫 git-codereview
的定製化 git
命令列工具,它可以簡化與 Gerrit 的互動流程。
執行下面的命令安裝 git-codereview
命令列工具:
$ go get -u golang.org/x/review/git-codereview
確保 git-codereview
被正確安裝到你的終端路徑裡,這樣 git
命令才可以找到它,檢查一下:
git codereview help
正確列印出幫助資訊,而且沒有任何錯誤。如果發現有錯誤,確保環境變數 $PATH
裡有 $GOPATH/bin
這個值。
在 Windows 系統上,當使用 git-bash 的時候你必須確保 git-codereview.exe
已經存在於你的 git
exec-path 上了。可以執行 git --exec-path
來找到正確的位置然後建立一個軟連結指向它或者直接從 $GOPATH/bin
目錄下拷貝這個可執行檔案到 exec-path。
貢獻程式碼之前
Go 語言專案歡迎提交程式碼補丁,但是為了確保很好地進行協調,你應該在開始提交重大程式碼變更之前進行必要的討論。我們建議你把自己的意圖或問題要不先提交到一個新的 GitHub issue,要不找到一個和你的問題相同或類似的 issue 跟進檢視。
檢查 issue 列表
不管你是已經明確了要提交什麼程式碼,還是你正在搜尋一個想法,你都應該先到 issue 列表 搜尋一下。所有 Issues 被已經分門別類以及被用來管理 Go 開發的工作流。
大多數 issues 會被標記上以下眾多的工作流標籤中的其中一個:
- NeedsInvestigation: 該 issue 並不能被完全清晰地解讀,需要更多的分析去找到問題的根源
- NeedsDecision: 該 issue 已經在相當程度上被解讀,但是 Go 團隊還沒有得出一個最好的方法去解決它。最好等 Go 團隊得出了最終的結論之後才開始寫程式碼修復它。如果你對解決這個 issue 感興趣,而且這個 issue 已經過了很久都沒得出最終結論,隨時可以在該 issue 下面發表評論去"催促"維護者。
- NeedsFix: 該 issue 可以被完全清晰地解讀而且可以開始寫程式碼修復它。
你可以使用 GitHub 的搜尋功能去搜尋一個 issue 然後搭把手幫忙解決它。例子:
- Issues that need investigation:
is:issue is:open label:NeedsInvestigation
- Issues that need a fix:
is:issue is:open label:NeedsFix
- Issues that need a fix and have a CL:
is:issue is:open label:NeedsFix "golang.org/cl"
- Issues that need a fix and do not have a CL:
is:issue is:open label:NeedsFix NOT "golang.org/cl"
新開一個關於任何新問題的 issue
除了一些很瑣碎的變更之外,所有的程式碼貢獻都應該關聯到一個已有的 issue。你隨時可以新開一個 issue 來討論你的相關計劃。這個流程可以讓所有人都能夠參與驗證程式碼的設計,同時幫忙減少一些重複的工作,以及確保這個想法是符合這門語言和相關工具的目標和理念的。還有就是能在真正開始寫程式碼之前就檢查這個程式碼設計是否合理;程式碼評審工具不是用來討論高層次問題的。
在規劃你的程式碼變更工作的時候,請知悉 Go 語言專案遵循的是 6 個月開發週期。在每一個 6 個月週期的後半部分是長達 3 個月的新功能特性凍結期:這期間我們只接受 bug 修復和文件更新相關的變更。在凍結期內還是可以提交新的變更的,但是這些變更的程式碼在凍結期結束之前不會被合併入主分支。
那些針對語言、標準庫或者工具的重大變更必須經過變更提議流程才能被接受。
敏感性的安全相關的 issues 只能上報到 security@golang.org 郵箱!
通過 GitHub 提交一個變更
我們鼓勵那些初次提交程式碼並且已經相當熟悉 GitHub 工作流的貢獻者通過標準的 GitHub 工作流給 Go 提交程式碼。儘管 Go 的維護者們是使用 Gerrit 來進行程式碼評審,但是不用擔心,會有一個叫 Gopherbot 的機器人專門來做把 GitHub PR 同步到 Gerrit 上的工作。
就像你通常情況下那樣新建一個 pull request,Gopherbot 會建立一個對應的 Gerrit 變更頁面然後把指向該 Gerrit 變更頁面的連結釋出在 GitHub PR 裡面;所有 GitHub PR 的更新都會被同步更新到 Gerrit 裡。當有人在 Gerrit 的程式碼變更頁面裡發表評論的時候,這些評論也會被同步更新回 GitHub PR 裡,因此 PR owner 將會收到一個通知。
需要謹記於心的東西:
- 如果要在 GitHub PR 裡進行程式碼更新的話,只需要把你最新的程式碼推送到對應的分支;你可以新增更多的 commits、或者做 rebase 和 force-push 操作(這些方式都是可以接受的)。
- 一旦 GitHub PR 被接受,所有的 commits 將會被合併成一條,而且最終的 commit 資訊將由 PR 的標題和描述聯結而成。那些單獨的 commit 描述將會被丟棄掉。檢視寫好 Commits 資訊獲取更多的建議。
- Gopherbot 無法逐字逐句地把程式碼評審的資訊同步回 Github: 僅僅是 (未經格式化的) 全部評論的內容會被同步過去。請記住,你總是可以訪問 Gerrit 去檢視更細粒度和格式化的內容。
通過 Gerrit 提交一個變更
一般來說,我們基本不可能在 Gerrit 和 GitHub 之前完整地同步所有資訊,至少在現階段來說是這樣,所以我們推薦你去學習一下 Gerrit。這個不同於 GitHub 卻同樣強大的工具,而且熟悉它能幫助你更好地理解我們的工作流。
概述
這是一個關於整個流程的概述:
-
步驟 1: 從
go.googlesource.com
克隆 Go 的原始碼下來,然後通過編譯和測試一次確保這份原始碼是完整和穩定的:powershell $ git clone https://go.googlesource.com/go $ cd go/src $ ./all.bash # compile and test
-
步驟 2: 從 master 分支上拉出一條新分支並在這個分支上準備好你的程式碼變更。使用
git codereview change
來提交程式碼變更;這將會在這個分支上新建或者 amend 一條單獨的 commit。powershell $ git checkout -b mybranch $ [edit files...] $ git add [files...] $ git codereview change # create commit in the branch $ [edit again...] $ git add [files...] $ git codereview change # amend the existing commit with new changes $ [etc.]
-
步驟 3: 重跑
all.bash
指令碼,測試你的程式碼變更。powershell $ ./all.bash # recompile and test
-
步驟 4: 使用
git codereview mail
命令傳送你的程式碼變更到 Gerrit 進行程式碼評審 (這個過程並不使用 e-mail,請忽略這個奇葩名字)。powershell $ git codereview mail # send changes to Gerrit
-
步驟 5: 經過一輪程式碼評審之後,把你新的程式碼變更依附在同一個單獨 commit 上然後再次使用 mail 命令傳送到 Gerrit:
powershell $ [edit files...] $ git add [files...] $ git codereview change # update same commit $ git codereview mail # send to Gerrit again
這個章節剩下的內容將會把上面的步驟進行詳細的講解。
步驟 1: 克隆 Go 語言的原始碼
除了你近期安裝的 Go 版本,你還需要有一份從正確的遠端倉庫克隆下來的本地拷貝。你可以克隆 Go 語言原始碼到你的本地檔案系統上的任意路徑下,除了你的 GOPATH
環境變數對應的目錄。從 go.googlesource.com
克隆下來 (不是從 Github):
$ git clone https://go.googlesource.com/go
$ cd go
步驟 2: 在新分支上準備好程式碼變更
每一次程式碼變更都必須在一條從 master 拉出來的獨立分支上開發。你可以使用正常的 git
命令來新建一條分支然後把程式碼變更新增到暫存區:
$ git checkout -b mybranch
$ [edit files...]
$ git add [files...]
使用 git codereview change
而不是 git commit
命令來提交變更。
$ git codereview change
(open $EDITOR)
你可以像往常一樣在你最喜歡的編輯器裡編輯 commit 的描述資訊。 git codereview change
命令會自動在靠近底部的地方新增一個唯一的 Change-Id 行。那一行是被 Gerrit 用來匹配歸屬於同一個變更的多次連續的上傳。不要編輯或者是刪除這一行。一個典型的 Change-Id 一般長的像下面這樣:
Change-Id: I2fbdbffb3aab626c4b6f56348861b7909e3e8990
這個工具還會檢查你是否有使用 go fmt
命令對程式碼進行格式化,以及你的 commit 資訊是否遵循建議的格式。
如果你需要再次編輯這些檔案,你可以把新的程式碼變更暫存到暫存區然後重跑 git codereview change
: 後續每一次執行都會 amend 到現存的上一條 commit 上,同時保留同一個 Change-Id。
確保在每一條分支上都只存在一個單獨的 commit,如果你不小心新增了多條 commits,你可以使用 git rebase
來把它們合併成一條。
步驟 3: 測試你的程式碼變更
此時,你已經寫好並測試好你的程式碼了,但是在提交你的程式碼去進行程式碼評審之前,你還需要對整個目錄樹執行所有的測試來確保你的程式碼變更沒有對其他的包或者程式造成影響/破壞:
$ cd go/src
$ ./all.bash
(如果是在 Windows 下構建,使用 all.bat
;還需要在儲存 Go 語言原始碼樹的目錄下為引導編譯器設定環境變數 GOROOT_BOOTSTRAP。)
在執行和列印測試輸出一段時間後,這個命令在結束前列印的最後一行應該是:
ALL TESTS PASSED
你可以使用 make.bash
而不是 all.bash
來構建編譯器以及標準庫而不用執行整個測試套件。一旦 go
工具構建完成,一個 bin/go
可執行程式會被安裝在你前面克隆下來的 Go 語言原始碼的根目錄下,然後你可以在那個目錄下直接執行那個程式。可以檢視快速測試你的程式碼變更這個章節。
步驟 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
如果有錯誤,檢視 mail 命令錯誤大全和故障排除。
如果你的程式碼變更關聯到一個現存的 GitHub issue 而且你也已經遵循了建議的 commit 資訊格式,機器人將會在幾分鐘更新那個 issue:在評論區新增 Gerrit 變更頁面的連結。
步驟 5: 程式碼評審之後修正變更
Go 語言的維護者們會在 Gerrit 上對你的程式碼進行 review,然後你會收到一堆郵件通知。你可以在 Gerrit 上檢視詳情以及發表評論,如果你更傾向於直接使用郵件回覆,也沒問題。
如果你需要在一輪程式碼評審之後更新程式碼,直接在你之前建立的同一條分支上編輯程式碼檔案,接著新增這些檔案進 Git 暫存區,最後通過 git codereview change
amend 到上一條 commit:
$ git codereview change # amend current commit
(open $EDITOR)
$ git codereview mail # send new changes to Gerrit
要是你不需要更改 commit 描述資訊,可以直接在編輯器儲存然後退出。記得不要去碰那一行特殊的 Change-Id。
再次確保你在每一條分支上只保留了一個單獨的 commit,如果你不小心新增了多條 commits,你可以使用 git rebase
來把它們合併成一條。
良好的 commit 資訊
Go 語言的 commit 資訊遵循一系列特定的慣例,我們將在這一章節討論。
這是一個良好的 commit 資訊的例子:
math: improve 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 https://wikipedia.org/wiki/McGillicutty_Algorithm
Fixes #159
首行
變更資訊的第一行照慣例一般是一短行關於程式碼變更的概述,字首是此次程式碼變更影響的主要的包名。
作為經驗之談,這一行是作為 "此次變更對 Go 的 _________ 部分進行了改動" 這一個句子的補全資訊,也就是說這一行並不是一個完整的句子,因此並不需要首字母大寫,僅僅只是對於程式碼變更的歸納總結。
緊隨第一行之後的是一個空行。
主幹內容
描述資訊中剩下的內容會進行詳盡地闡述以及會提供關於此次變更的上下文資訊,而且還要解釋這個變更具體做了什麼。請用完整的句子以及正確的標點符號來表達,就像你在 Go 程式碼裡的註釋那樣。不要使用 HTML、Markdown 或者任何其他的標記語言。
新增相關的資訊,比如,如果是效能相關的改動就需要新增對應的壓測資料。照慣例會使用 benchstat 工具來對壓測資料進行格式化處理,以便寫入變更資訊裡。
引用 issues
接下來那個特殊的表示法 "Fixes #12345" 把程式碼變更關聯到了 Go issue tracker 列表裡的 issue 12345。當這個程式碼變更最終實施之後 (也就是合入主幹),issue tracker 將會自動標記那個 issue 為"已解決"並關閉它。
如果這個程式碼變更只是部分解決了這個 issue 的話,請使用 "Updates #12345",這樣的話就會在那個 issue 的評論區裡留下一個評論把它連結回 Gerrit 上的變更頁面,但是在該程式碼變更被實施之後並不會關閉掉 issue。
如果你是針對一個子倉庫傳送的程式碼變更,你必須使用 GitHub 支援的完全形式的語法來確保這個程式碼變更是連結到主倉庫的 issue 上去的,而非子倉庫。主倉庫的 issue tracker 會追蹤所有的 issues,正確的格式是 "Fixes golang/go#159"。
程式碼評審流程
這個章節是對程式碼評審流程的詳細介紹以及如何在一個變更被髮送之後處理反饋。
常見的新手錯誤
當一個變更被髮送到 Gerrit 之後,通常來說它會在幾天內被分門別類。一個維護者將會檢視並提供一些初始的評審,對於初次提交程式碼貢獻者來說,這些評審通常集中在基本的修飾和常見的錯誤上。
內容包括諸如:
- Commit 資訊沒有遵循建議的格式
- 沒有連結到對應的 GitHub issue。大部分程式碼變更需要連結到對應的 GitHub issue,說明這次變更修復的 bug 或者實現的功能特性,而且在開始這個變更之前,issue 裡應該已經達成了一致的意見。Gerrit 評審不會討論程式碼變更的價值,僅僅是討論它的具體實現。
- 變更如果是在開發週期的凍結階段被髮送到 Gerrit 上的,也就是說彼時 Go 程式碼樹是不接受一般的變更的,這種情況下,一個維護者可能會在評審程式碼時留下一行這樣的評論:R=go.1.12,意思是這個程式碼變更將會在下一個開發視窗期開啟 Go 程式碼樹的時候再進行評審。如果你知道那不是這個程式碼變更應該被評審的正確的時間範圍,你可以自己加上這樣的評論:R=go1.XX 來更正。
Trybots
在第一次看過你的程式碼變更之後,維護者會啟動一些 trybots,這是一個會在不同的 CPU 架構的機器上執行完整測試套件的伺服器叢集。大部分 trybots 會在幾分鐘內執行完成,之後會有一個可以檢視具體結果的連結出現在 Gerrit 變更頁面上。
如果 trybot 最後執行失敗了,點選連結然後檢視完整的日誌,看看是在哪個平臺上測試失敗了。儘量嘗試去弄明白失敗的原因,然後更新你的程式碼去修復它,最後重新上傳你的新程式碼。維護者會重新啟動一個新的 trybot 再跑一遍,看看問題是不是已經解決了。
有時候,Go 程式碼樹會在某些平臺上有長達數小時的執行失敗;如果 trybot 上報的失敗的問題看起來和你的這次程式碼變更無關的話,到構建皮膚上去檢視近期內的其他 commits 在相同的平臺上是不是有出現過這種一樣的失敗。如果有的話,你就在 Gerrit 變更頁面的評論區裡說明一下這個失敗和你的程式碼變更無關,以此讓維護者知悉這種情況。
評審
Go 語言社群非常重視全面的評審。你要把每一條評審的評論的當成一張罰單:你必須通過某種方式把它"關掉",或者是你把評論裡建議的修改實現一下,或者是你說服維護者那部分不需要修改。
在你更新了你的程式碼之後,過一遍評審頁面的所有評論,確保你已經全部回覆了。你可以點選 "Done" 按鈕回覆,這表示你已經實現了評審人建議的修改,否則的話,點選 "Reply" 按鈕然後解釋一下你為什麼還沒修改、或者是你已經做了其他地方的修改並覆蓋了這一部分。
一般來說,程式碼評審裡會經歷多輪的評審,期間會有一個或者多個評審人不斷地發表新的程式碼審查評論然後等待提交者修改更新程式碼之後繼續評審,這是很正常的。甚至一些經驗老到的程式碼貢獻者也會經歷這種迴圈,所以不要因此而被打擊到。
投票規則
在評審人們差不多要得出結論之時,他們會對你的此次程式碼變更進行"投票"。Gerrit 的投票系統包含了一個在 [-2, 2] 區間的整數:
- +2: 同意此次程式碼變更被合入到主分支。只有 Go 語言的維護者們才有許可權投 +2 的票。
- +1: 這個程式碼變更看起來沒什麼問題,不過要麼是因為評審人還要求對程式碼做一些小的改動、要麼是因為該評審人不是一個維護者而無法直接批准這個變更,但是該評審人支援批准這個變更。
- -1: 這個程式碼變更並不是很合理但可能有機會做進一步的修改。如果你得到了一個 -1 票,那一定會有一個明確的解釋告訴你為什麼。
- -2: 一個維護者否決了這個程式碼變更並且不同意合入主幹。同樣的,會有一個明確的解釋來說明原因。
提交一個核準的變更
在一個程式碼變更被投了一個 +2 票之後,投下這票的核準人將會使用 Gerrit 的使用者介面來將程式碼合併入主幹,這個操作被稱為"提交變更"。
之所以把核准和提交拆分成兩步,是因為有些時候維護者們可能並不想把剛剛批准的程式碼變更立刻合入主幹,比如,彼時可能正處於 Go 程式碼樹的暫時凍結期。
提交一個變更將會把程式碼合入主倉庫,程式碼變更的描述資訊裡會包含一個指向對應程式碼評審頁面的連結,而具體程式碼評審頁面處也會更新一個連結指向倉庫裡的此次程式碼變更 commit。把程式碼變更合入主幹時使用的是 Git 的 "Cherry Pick" 命令,因此在主倉庫裡的關於此次程式碼變更的 commit 雜湊 ID 會被這個提交操作更改。
如果你的變更已經被批准了好幾天了,但是一直沒有被提交到主倉庫,你可以在 Gerrit 寫個評論要求合入。
更多資訊
除了這裡的資訊,Go 語言社群還維護了一個程式碼評審的 wiki 頁面。隨時歡迎你在學習相關的評審流程之時為這個頁面貢獻、補充新內容。
其他主題
這個章節收集了一些除了 issue/edit/code review/submit 流程之外的註解資訊。
版權標頭
Go 語言倉庫裡的檔案不會儲存一份作者列表,既是為了避免雜亂也是為了避免需要實時更新這份列表。相反的,你的名字將會出現在變更日誌和貢獻者檔案裡,也可能會出現在作者檔案裡。這些檔案是定期從 commit 日誌上自動生成的。作者檔案定義了哪些人是 “Go 語言作者” - 版權持有者。
如果你在提交變更的時候有新新增的檔案,那麼應該使用標準的版權頭:
// Copyright 2020 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.
(如果你此刻是在 2021 年或者往後的時間閱讀這份文件,請使用你當前的年份。) 倉庫裡的檔案版權生效於被新增進去的當年,不要在你變更的檔案裡更改版權資訊裡的年份。
mail 命令錯誤大全和故障排除
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
然後通過以下命令修改你的 commit 資訊,更正裡面的使用者名稱和郵箱:
$ git commit --amend --author="Author Name <email@address.com>"
最後執行一下的命令再重試一次:
$ git codereview mail
快速測試你的程式碼變更
如果每一次單獨的程式碼變更都對整個程式碼樹執行 all.bash
指令碼的話太費勁了,儘管我們極力建議你在傳送程式碼變更之前跑一下這個指令碼,然而在開發的期間你可能只想要編譯和測試那些你涉及到的包。
- 通常來說,你可以執行
make.bash
而不是all.bash
來只構建 Go 工具鏈,而不需要執行整個測試套件。或者你可以執行run.bash
來執行整個測試套件而不構建 Go 工具鏈。你可以把all.bash
看成是依次執行make.bash
和run.bash
。 - 在這個章節,我們會把你存放 Go 語言倉庫的目錄稱為
$GODIR
。make.bash
指令碼構建的go
工具會被安裝到$GODIR/bin/go
然後你就可以呼叫它來測試你的程式碼了。例如,如果你修改了編譯器而且你想要測試看看會對你自己專案裡的測試套件造成怎樣的影響,直接用它執行go test
:powershell $ cd <MYPROJECTDIR> $ $GODIR/bin/go test
- 如果你正在修改標準庫,你可能不需要重新構建編譯器:你可以直接在你正在修改的包裡跑一下測試程式碼就可以了。你可以使用平時用的 Go 版本或者從克隆下來的原始碼構建而成的編譯器 (有時候這個是必須的因為你正在修改的標準庫程式碼可能會需要一個比你已經安裝的穩定版更新版本的編譯器) 來做這件事。
powershell $ cd $GODIR/src/hash/sha1 $ [make changes...] $ $GODIR/bin/go test .
- 如果你正在修改編譯器本身,你可以直接重新編譯
編譯
工具(這是一個使用go build
命令編譯每一個單獨的包之時會呼叫到的一個內部的二進位制檔案)。完成之後,你會想要編譯或者執行一些程式碼來測試一下:powershell $ cd $GODIR/src $ [make changes...] $ $GODIR/bin/go install cmd/compile $ $GODIR/bin/go build [something...] # test the new compiler $ $GODIR/bin/go run [something...] # test the new compiler $ $GODIR/bin/go test [something...] # test the new compiler
同樣的操作可以應用到 Go 工具鏈裡的其他內部工具,像是 asm
, cover
, link
等等。直接重新編譯然後使用 go install cmd/<TOOL>
命令安裝,最後使用構建出來的 Go 二進位制檔案測試一下。
- 除了標準的逐包測試,在
$GODIR/test
目錄下有一個頂級的測試套件,裡面包含了多種黑盒和迴歸測試。這個測試套件是包含在all.bash
指令碼里執行的,不過你也可以手動執行它:powershell $ cd $GODIR/test $ $GODIR/bin/go run run.go
向子倉庫提交貢獻 (golang.org/x/...)
如果你正在向一個子倉庫提交貢獻,你需要使用 go get
來獲取對應的 Go 包。例如,如果要向 golang.org/x/oauth2
包貢獻程式碼,你可以通過執行以下的命令來獲取程式碼:
$ go get -d golang.org/x/oauth2/...
緊接著,進入到包的源目錄($GOPATH/src/golang.org/x/oauth2),然後按照正常的程式碼貢獻流程走就行了。
指定一個評審人/抄送其他人
除非有明確的說明,比如在你提交程式碼變更之前的討論中,否則的話最好不要自己指定評審人。所有的程式碼變更都會自動抄送給 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 工作流裡有其他人把 commits 依附到你的 PR 上了)。你可以匯入這些他人提交的變更到你的本地 Git 分支上。在 Gerrit 的評審頁面,點選右上角的 "Download ▼" 連結,複製 "Checkout" 命令然後在你的本地 Git 倉庫下執行它。這個命令類似如下的格式:
$ git fetch https://go.googlesource.com/review refs/changes/21/13245/1 && git checkout FETCH_HEAD
如果要撤銷,切換回你之前在開發的那個分支即可。
設定 Git 別名
git codereview
相關的命令可以直接在終端鍵入對應的選項執行,例如:
$ git codereview sync
不過給 git codereview
子命令命令設定別名會更方便使用,上面的命令可以替換成:
$ git sync
git codereview
的子命令的名字是排除了 Git 本身的命令關鍵字而挑選出來的,所以不用擔心設定了這些別名會和 Git 本身的命令衝突。要設定這些別名,複製下面的文字到你的 Git 配置檔案裡(通常是在 home 路徑下的 .gitconfig
檔案):
[alias]
change = codereview change
gofmt = codereview gofmt
mail = codereview mail
pending = codereview pending
submit = codereview submit
sync = codereview sync
傳送多個依賴的變更
老司機使用者可能會想要把相關的 commits 疊加到一個單獨的分支上。Gerrit 允許多個程式碼變更之間相互依賴,形成這樣的依賴鏈。每一個變更需要被單獨地核準和提交,但是依賴對於評審人來說是可見的。
要傳送一組依賴的程式碼更改,請將每個變更作為不同的 commit 儲存在同一分支下,然後執行:
$ git codereview mail HEAD
要確保顯示地指定 HEAD
,不過這在單個變更的場景裡通常是不需要指定的。
英文原文地址
https://golang.org/doc/contribute.html
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- BBNorm官方指導文件翻譯ORM
- [翻譯]ElasticSearch官方文件-查詢語言Elasticsearch
- 聊聊原始碼貢獻這件大事原始碼
- GO語言————4.9、指標Go指標
- Go 語言 HTTP Server 原始碼分析GoHTTPServer原始碼
- 【譯】Go語言宣告語法Go
- 舒服,給Spring貢獻一波原始碼。Spring原始碼
- Go語言——sync.Map原始碼分析Go原始碼
- go 語言指標學習Go指標
- Go 語言讀寫 Excel 文件GoExcel
- [譯] Go 語言實戰: 編寫可維護 Go 語言程式碼建議Go
- Go 語言編譯期斷言Go編譯
- Go語言—sync.Cond原始碼分析Go原始碼
- Go語言Context包原始碼學習GoContext原始碼
- Go 語言指標符號 *和&Go指標符號
- go語言實戰嚮導Go
- [翻譯] Go 語言入門Go
- 如何給 swoft 貢獻程式碼
- 如何為PHP貢獻程式碼PHP
- 如何為 PHP 貢獻程式碼PHP
- 我給Apache頂級專案貢獻了點原始碼。Apache原始碼
- 向微軟官方貢獻 @types 包後引發的思考微軟
- Chrome開發者工具的官方文件及其他前端語言開發文件Chrome前端
- Moya官方文件翻譯
- go語言編譯過程概述Go編譯
- Go語言交叉編譯工具goxGo編譯
- 個人經驗分享如何閱讀Go語言原始碼Go原始碼
- Citus 11(分散式 PostgreSQL) 文件貢獻與本地執行分散式SQL
- Go語言內幕(2):深入 Go 編譯器Go編譯
- go語言go get 匯入官方依賴的解決方法Go
- Go語言使用swagger生成介面文件GoSwagger
- 徹底學會 Go 指標 -- 就要學習 Go 語言Go指標
- Go 是物件導向的語言嗎?Go物件
- contributions該不該譯成“貢獻”?
- 蘋果的貢獻蘋果
- [譯] AsyncDisplayKit/Texture 官方文件(1)
- docker官方文件翻譯3Docker
- [譯] AsyncDisplayKit/Texture 官方文件(2)