簡介: 代碼評審中一樣存在着「Talk is cheap. Show me the code」,語言無力時,直接上代碼吧。這就是咱們今天要討論的話題——代碼評審中的代碼協同。
git
做者 | 知憂
來源 | 阿里技術公衆號服務器
大神說:「Show me the code」,因而就有了代碼評審。併發
「Talk is cheap. Show me the code.」
——Linus Torvalds, founder of Linux and Git.
代碼評審中一樣存在着「Talk is cheap. Show me the code」,語言無力時,直接上代碼吧。這就是咱們今天要討論的話題——代碼評審中的代碼協同。工具
一 基於郵件列表的代碼評審fetch
這是一種和代碼倉庫鬆耦合的代碼評審模式,100%的代碼都要經由一位或多位「仁慈的獨裁者」(benevolent dictator)代碼評審後才能合併入代碼倉庫。這種開發模式還須要開發者掌握一些命令行操做技巧以便完成代碼在倉庫和郵件列表之間的轉換。採用這個模式的項目很少,不過 Linux、Git 開源社區就是按照這種模式運做的。this
1 代碼和郵件的相互轉換阿里雲
代碼轉換爲電子郵件,要使用 git format-patch 命令。例以下面的命令將指定範圍的代碼提交(例如在 origin/master 以後的新提交)轉換爲電子郵件:spa
git format-patch origin/master..HEAD
生成的補丁文件的格式以下所示:命令行
郵件頭中的 Subject: 字段是郵件標題,使用 [PATCH] 做爲標題前綴,以提交說明的第一行做爲標題內容。調試
更多的提交說明做爲郵件內容,和郵件頭之間用一個空行分隔開。
用分隔符 --- 做爲提交說明的結束。
在分隔符 --- 和 diff --git 開始的補丁內容之間的文字被忽略。一般此處內容是提交的變動統計,開發者也能夠在此處寫入不宜列入提交說明中的附加說明。
git format-patch 命令有不少參數,要結合不一樣場景使用,例如:
一個特性由多個提交構成,分散在多個提交中的提交說明難以描述整個特性,可使用 --cover-letter 參數,生成一封編號爲 0000 的郵件,做爲後續提交的摘要說明,便於評審者理解代碼。
一個特性一般會屢次迭代,就須要爲每次迭代設置不一樣的版本。這就要用到 -v {num} 參數指定補丁的版本。版本將體如今郵件標題中,例如第二版本的補丁,郵件標題將使用 [PATCH v2] 做爲前綴。
回覆特定郵件,以便造成可追蹤的郵件線索,使用參數 --in-reply-to="{Message-ID}",爲電子郵件生成相關的 In-Reply-To: 和 References: 頭信息。
默認提交自己的做者、提交說明的簽名區(trailer)說起的貢獻者會自動添加爲郵件的收件人。要添加更多參與者,可使用 --to={email}、--cc={email} 參數。
將電子郵件轉換爲代碼,則使用命令 git am [options...] mail... 。該命令會將郵件正確轉換爲 Git 倉庫中的提交。
使用 git send-email 命令,將包含代碼提交的郵件發送到郵件列表。
2 評審中的代碼片斷轉換爲提交
代碼評審以郵件回覆的方式完成。注意郵件回覆都要求用純文本格式,不然會被郵件服務器退信。
代碼評審中發現小的文字錯誤,例如將 warning 寫成了 waring,評審者可能作出以下簡潔的回覆:
s/waring/warning/
這種約定俗成的格式大概是源於 sed 命令實現文本替換的語法。
評審者有時候會在回覆中貼上大段的代碼補丁,爲了使代碼補丁和郵件上下文作出區分,會使用特殊的剪刀分隔符將郵件中的評論和代碼補丁分隔開。
Subject: Re: whatever thread you're in
Somebody else said:
blah blah blah
I disagree. You should do it like this instead:
-- >8 --
first line of commit message
diff --git ...
上面是 Peff(Jeff King)在郵件中給出的一個示範,看到其中的剪刀分隔符了麼?剪刀分隔符由多個減號(穿孔的分割線)和一個剪刀符號組成至少8個字符的分隔符。可選的分隔符有:-- 8< -- 、-- >8 -- 、-- %< -- 或 --- >% --- 等。
使用 git am --scissors 命令,可以識別郵件中的剪刀分隔符,將郵件中的代碼轉換爲提交。
3 爲提交貢獻者署名
Git的提交元信息中只包含兩個署名信息,一個是提交的原始做者(Author),一個是將提交合入倉庫或者對提交作了修補的提交者(Committer),而在提交評審過程當中有過貢獻的人每每不僅兩人,如何致敬貢獻者呢?Git 社區的實踐是在提交尾部(trailer)添加貢獻者簽名。貢獻者簽名由一個被動語態的關鍵字和貢獻者ID組成,例如:
Signed-off-by: User < Email > :一般由代碼的貢獻者(Author)和代碼合入時的提交者(Committer)提供的簽名。可由命令 git commit -s 、 git am -s 等命令自動添加。
Reported-by: User < Email > :問題的報告者。
Helped-by: User < Email >:對提交有過幫助的人。
Reviewed-by: User < Email > :評審者。
能夠經過 Git 項目倉庫的提交歷史,看到更多的簽名示例。
4 使用 GitHub PR 實現代碼到郵件的轉換
一個名爲 GitGitGadget 工具藉助 GitHub 強大的擴展能力,經過向 gitgitgadget/git 倉庫發送 pull request,實現提交到郵件的轉換,併發送到 Git 項目的郵件列表中。使用 GitGitGadget 參與 Git 社區代碼貢獻詳見。
二 GitHub 代碼評審中的協同
GitHub 使用 pull request 進行代碼評審,評論中的代碼塊兒也能夠轉換爲提交。
1 代碼評論中嵌入代碼塊
下圖中,點擊評論工具欄第一個按鈕,能夠在評論中嵌入代碼塊:
2 評論中代碼塊轉換爲提交
對 pull request 的源倉庫具備寫權限的用戶,能夠將評審中的代碼庫轉換爲提交,以下圖所示:
因而代碼評審中會增長一個新的修正提交。
GitHub 的這個功能對於代碼評審中發現的一些小問題,仍是很是方便的。可是大的修改就無能爲力了。
3 線下評審
對於功能複雜的 pull request,在線上瀏覽代碼不方便,也不能線上調試代碼,這時線下獲取並瀏覽代碼,就很是有必要了。
GitHub 的代碼倉庫中爲每個代碼評審設置了特殊的關聯引用:
refs/pull/{ID}/head :關聯 pull request 的源提交。
refs/pull/{ID}/merge :對於沒有衝突的 pull request,這個引用指向一個成功的合併提交。
代碼評審者使用以下命令能夠獲取 pull request (例如編號爲 123 的 PR)指向的提交:
git fetch origin refs/pull/123/head
git switch -d FETCH_HEAD
評審者能夠線下調試 pull request 指向的代碼,可是對代碼作出的本地修改,沒有辦法直接更新到線上的代碼評審中。
阿里巴巴的雲效Codeup,支持線下到線上的代碼協同。
三 雲效Codeup代碼評審中的協同
不管是 GitHub 仍是 Gitlab,開發者建立代碼評審首先須要將代碼推送到線上獨立的分支中(不管是在線上的派生倉庫,仍是目標倉庫),而後再經過網頁選擇來源倉庫、分支及目標倉庫、分支,建立代碼評審。
GitHub 和 Gitlab 這種代碼評審方式,或者要引入冗餘的派生倉庫,或者須要爲開發者賦予在倉庫中的寫入權限,並容易引起雜亂的分支管理。
1 適合主幹開發的無分支建立代碼評審
雲效 Codeup 能夠經過 git push 命令在客戶端直接建立代碼評審,無需建立派生倉庫或者在倉庫中建立特性分支。例如在客戶端執行以下命令:
git push origin HEAD:refs/for/master/topic1
該命令會在服務端建立新的代碼評審,或者若是已經存在相同用戶、相同命令建立的代碼評審則會更新評審中的提交。
建議安裝咱們開源的 git-repo 工具,則能夠用更簡單的命令行,實現從客戶端建立/更新代碼評審。
git pr
2 線下評審,線上協同
和 GitHub 相似,雲效 Codeup 建立的代碼評審都有一個特殊引用相關聯,格式爲:refs/merge-requests/{ID}/head。
代碼評審者可使用 git fetch 命令獲取特定的代碼評審(以編號123爲例)指向的代碼,進行線下代碼評審。
git fetch origin refs/merge-requests/123/head
git switch -d FETCH_HEAD
若是安裝了 git-repo,可使用下面更爲簡潔的命令:
git download 123
代碼評審者除了能夠在本地倉庫中瀏覽、調試代碼,還能夠更新代碼、建立提交,而後將本地新增提交更新到線上的代碼評審中。命令示例以下:
git pr -c 123
在雲效 Codeup,開發者和評審者能夠基於代碼評審進行更爲流暢的代碼協同。
3 Git proc-receive 掛鉤
上述「線下評審、線上協同」功能的核心是 Git 的 proc-receive 掛鉤和 report-status-v2 新能力。這一功能由阿里巴巴貢獻給 Git 社區,並在 Git 2.29.0 發佈。
雲效 Codeup 聚集了阿里巴巴最新的代碼託管、代碼協同技術,但願可以造福更多中國和世界的開發者。
原文連接本文爲阿里雲原創內容,未經容許不得轉載。