代碼檢視工具Gerrit的日常使用

1, Gerrit是什么?

Gerrit實(shí)際上一個(gè)Git服務(wù)器,它為在其服務(wù)器上托管的Git倉(cāng)庫(kù)提供一系列權(quán)限控制,以及一個(gè)用來做Code Review是Web前臺(tái)頁(yè)面。當(dāng)然,其主要功能就是用來做Code Review。

2, Gerrit用戶配置

  • Email激活
    Gerrit賬戶的設(shè)置界面,點(diǎn)擊“Contact Information”進(jìn)入Email Register頁(yè)面,輸入自己的郵箱賬戶(此郵箱需要與自己的Git配置一致)。可以配置多個(gè)Email賬號(hào)。
Contact Information
  • SSH key配置
    通過以下命令生成并讀取本機(jī)ssh key:
ssh-keygen -t rsa
cat ~/.ssh/id_rsa.pub

Copy key的內(nèi)容,在Gerrit賬戶的設(shè)置頁(yè)面“SSH Public Key”中加入即可。

ssh-key

3, Gerrit日常使用

3.1 獲取代碼庫(kù)

登錄Gerrit后在Projects-->List, 選擇相應(yīng)工程your_project,進(jìn)入該工程的General界面。
選中“clone with commit-msg hook”和“SSH”:

git clone ssh://your_account@review.xxxxx.com:29418/your_project && scp -p -P 29418 your_account@review.xxxxx.com:hooks/commit-msg cic-android/.git/hooks/

拷貝以上命令在自己本地Git命令行窗口執(zhí)行即可拉取庫(kù)代碼。

3.2 Gerrit工作流程

3.2.1 上傳一個(gè)commit

Gerrit相對(duì)Git提供了一個(gè)特有的命名空間“refs/for/”用來定義我們的提交上傳到哪個(gè)branch,且可以用來區(qū)分我們的commit是提交到Gerrit進(jìn)行審核還是直接提交到Git倉(cāng)庫(kù),格式如下:

refs/for/<target-branch>

Push一個(gè)Commit到Gerrit:

$ git commit
$ git push origin HEAD:refs/for/master

直接Push一個(gè)commit到Git倉(cāng)庫(kù):(我們默認(rèn)配置成不允許)

$ git commit
$ git push origin HEAD:master

當(dāng)我們的commit Push到Gerrit等待review時(shí),Gerrit會(huì)將此commit保存在一個(gè)名為“refs/changes/xx/yy/zz”的一個(gè)暫存branch中。
其中zz為這個(gè)commit的patch set號(hào),yy是change號(hào),xx是change號(hào)的后兩位。

例如我們工程中的這個(gè)大明同學(xué)的提交:

http://review.xxxxx.com:9090/#/c/545/

一共提交了9次patch,那么第9個(gè)patch就保存在一個(gè)名為“refs/changes/45/545/9”的branch中。

可以通過Gerrit頁(yè)面中該commit右上角的Download按鈕驗(yàn)證,比如說我們選擇“Cherry Pick”, 命令如下:

git fetch ssh://your_account@review.xxxxx.com:29418/your_project refs/changes/45/545/9 && git cherry-pick FETCH_HEAD

在此,有必要說下幾個(gè)概念,以便理解:

  • Change
    一個(gè)Change包含一個(gè)Change-Id,這個(gè)Id就是通過我們拉取代碼庫(kù)的時(shí)候所拷貝的hooks(hooks/commit-msg)自動(dòng)生成的。
    包含一個(gè)或多個(gè)Patch Set,以及諸如Owner,Project,Target branch,Comments等信息。

  • Change-Id
    Change-Id是一串SHA-1字符串。有hooks自動(dòng)生成在我們的commit message下面:

Feature:Music play.
BugId:/
Description:Music play.

Change-Id: I3d087f04d9d94bfaa93b8609b988b300af537497

在一個(gè)project的每個(gè)branch中Change Id是唯一的。

  • Patch Set
    一個(gè)Patch Set就是一次commit,Gerrit會(huì)將其生成一個(gè)Branch暫存。Change中的每提交一個(gè)Patch Set表示這個(gè)Change的一個(gè)新的版本,自動(dòng)覆蓋前一個(gè)Patch Set, 默認(rèn)情況下,僅最后一個(gè)Patch Set是有意義的。Code Review通過時(shí),也僅僅是最后一個(gè)Patch Set會(huì)合并到指定的branch中。

個(gè)人Git工作原則一
** 永遠(yuǎn)是基于遠(yuǎn)程庫(kù)的最新代碼工作,盡量每一步操作(特別是add/commit/push)都通過git pull --rebase獲取一下當(dāng)前最新版本。**

根據(jù)以上原則,建議在將本地commit push到Gerrit之后,立馬reset掉,或者重新切換一個(gè)新的分支工作。

3.2.2 上傳一個(gè)新的patch set

當(dāng)我們的commit被reviewer打回來時(shí),我們可能需要修改并重新提交。
如果我們的代碼在本地分支已經(jīng)reset掉,可以通過Gerrit頁(yè)面提供的Download方式獲取:

// fetch and checkout the change
// (checkout command copied from change screen)
$ git fetch ssh://your_account@review.xxxxx.com:29418/your_project refs/changes/45/545/9 && git checkout FETCH_HEAD

如果之前是通過切換分支方式工作的,可以重新切換回包含此commit的分支而無(wú)需執(zhí)行上述命令,然后可以在此代碼基礎(chǔ)上進(jìn)行修改,重新add,amend commit:

// rework the change
$ git add <path-of-reworked-file>
...

// amend commit
$ git commit --amend

// push patch set
$ git push origin HEAD:refs/for/master

3.2.3 添加Reviewers

在Change界面添加相關(guān)reviewers.可以考慮使用自動(dòng)添加reviewers的插件

3.2.4 提交Change

Change一般配置成只有在Code-Review +2 以及Verified +1 的情況下才可以Submit。

Submit時(shí)可能會(huì)有沖突,界面會(huì)提示“Cannot Merge”字樣,此時(shí)可以先嘗試Gerrit頁(yè)面提供的Rebase功能做一次Rebase操作,如果提示沖突,則需在本地解決沖突后重新提交一個(gè)Patch Set到該Change上。

本地Rebase的一種流程:

// update the remote tracking branches
$ git fetch

// fetch and checkout the change
// (checkout command copied from change screen)
$ git fetch ssh://your_account@review.xxxxx.com:29418/your_project  refs/changes/74/67374/2 && git checkout FETCH_HEAD

// do the rebase
$ git rebase origin/master

// resolve conflicts if needed and stage the conflict resolution
  ...
$ git add <path-of-file-with-conflicts-resolved>

// continue the rebase
$ git rebase --continue

// push the commit with the conflict resolution as new patch set
$ git push origin HEAD:refs/for/master  

3.3 多Feature并行開發(fā)

Code Review需要時(shí)間,開發(fā)人員可以在此期間開發(fā)其他feature,這就產(chǎn)生了多feature并行開發(fā)的狀態(tài)。

為了保證減少?zèng)_突和依賴,每一個(gè)feature都應(yīng)該是在該feature自己的本地分支開發(fā),且此分支是基于遠(yuǎn)程分支(target branch)的當(dāng)前HEAD的。 也就是基于遠(yuǎn)程庫(kù)的最新代碼開發(fā),而不應(yīng)該依賴于code review中的某個(gè)、某些Change。

當(dāng)然,如果必要,你也可以基于一個(gè)正在code review的Change開發(fā)新的feature,這樣會(huì)產(chǎn)生依賴,可以在Gerrit中該Change的頁(yè)面看到“Related Changes”。這就要求reviewer也需要關(guān)注這個(gè)依賴關(guān)系,調(diào)整review時(shí)序。

根據(jù)以往的使用經(jīng)驗(yàn),強(qiáng)烈建議不要產(chǎn)生這種依賴,盡量使每一個(gè)Change提交都是無(wú)依賴的,避免Change的連環(huán)失敗導(dǎo)致各種解沖突的工作。

個(gè)人Git工作原則二
** 盡可能保證每一個(gè)Change的完整性以及獨(dú)立性,且越小越好。**

4, 進(jìn)階功能

4.1 Web頁(yè)面代碼修改

Gerrit提供了直接在Web頁(yè)面修改我們的patch代碼的功能,這對(duì)于我們做一些小的問題修改(比如格式化問題,命名不對(duì),多余的空格等)非常方便。

Edit

點(diǎn)擊Edit后,該工具欄顯示如下:

toolbar

可以在此對(duì)patch的文件進(jìn)行修改,刪除等。
如果想對(duì)文件中的某處進(jìn)行編輯,點(diǎn)擊進(jìn)入該文件的review界面:

page_edit

點(diǎn)擊編輯按鈕,進(jìn)入編輯模式,編輯完save:

save

會(huì)在Change頁(yè)面看到,點(diǎn)擊Publish Edit按鈕,Gerrit會(huì)自動(dòng)幫你生成一個(gè)包含剛剛修改的patch。

publish
patch

4.2 草稿箱功能

Gerrit可以作為一個(gè)自己的Change草稿箱,我們可以將一些還未完成,或者還不想提交review的Change上傳至此處。一來可以作為一個(gè)備份,另外在多人互相協(xié)助完成同一個(gè)功能,或是自己在多臺(tái)電腦(家里、辦公室)上處理未完成的工作。
不同于提交一個(gè)正式Change的“refs/for/”協(xié)議,提交一個(gè)Change到草稿箱的協(xié)議方式為“refs/drafts/”,如下:

$ git commit
$ git push origin HEAD:refs/drafts/luckyair

在Gerrit頁(yè)面的Drafts欄:

draft

草稿箱中的Change也可以很方便的轉(zhuǎn)換為正式的Change,而無(wú)需重新用“refs/for/”來提交,點(diǎn)擊Publish按鈕轉(zhuǎn)換為正式Change,也可以在此刪除此草稿。

publish draft
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容