原文:https://www.jianshu.com/p/b77fd16894b6
1, Gerrit是什麼?
Gerrit實際上一個Git服務器,它爲在其服務器上託管的Git倉庫提供一系列權限控制,以及一個用來做Code Review是Web前臺頁面。當然,其主要功能就是用來做Code Review。
2, Gerrit用戶配置
- Email激活
Gerrit賬戶的設置界面,點擊“Contact Information”進入Email Register頁面,輸入自己的郵箱賬戶(此郵箱需要與自己的Git配置一致)。可以配置多個Email賬號。
Contact Information
- SSH key配置
通過以下命令生成並讀取本機ssh key:
ssh-keygen -t rsa
cat ~/.ssh/id_rsa.pub
Copy key的內容,在Gerrit賬戶的設置頁面“SSH Public Key”中加入即可。
ssh-key
3, Gerrit日常使用
3.1 獲取代碼庫
登錄Gerrit後在Projects-->List, 選擇相應工程your_project,進入該工程的General界面。
選中“clone with commit-msg hook”和“SSH”:
git clone ssh://[email protected]:29418/your_project && scp -p -P 29418 [email protected]:hooks/commit-msg cic-android/.git/hooks/
拷貝以上命令在自己本地Git命令行窗口執行即可拉取庫代碼。
3.2 Gerrit工作流程
3.2.1 上傳一個commit
Gerrit相對Git提供了一個特有的命名空間“refs/for/”用來定義我們的提交上傳到哪個branch,且可以用來區分我們的commit是提交到Gerrit進行審覈還是直接提交到Git倉庫,格式如下:
refs/for/<target-branch>
Push一個Commit到Gerrit:
$ git commit
$ git push origin HEAD:refs/for/master
直接Push一個commit到Git倉庫:(我們默認配置成不允許)
$ git commit
$ git push origin HEAD:master
當我們的commit Push到Gerrit等待review時,Gerrit會將此commit保存在一個名爲“refs/changes/xx/yy/zz”的一個暫存branch中。
其中zz爲這個commit的patch set號,yy是change號,xx是change號的後兩位。
例如我們工程中的這個大明同學的提交:
http://review.xxxxx.com:9090/#/c/545/
一共提交了9次patch,那麼第9個patch就保存在一個名爲“refs/changes/45/545/9”的branch中。
可以通過Gerrit頁面中該commit右上角的Download按鈕驗證,比如說我們選擇“Cherry Pick”, 命令如下:
git fetch ssh://[email protected]:29418/your_project refs/changes/45/545/9 && git cherry-pick FETCH_HEAD
在此,有必要說下幾個概念,以便理解:
-
Change
一個Change包含一個Change-Id,這個Id就是通過我們拉取代碼庫的時候所拷貝的hooks(hooks/commit-msg)自動生成的。
包含一個或多個Patch Set,以及諸如Owner,Project,Target branch,Comments等信息。 -
Change-Id
Change-Id是一串SHA-1字符串。有hooks自動生成在我們的commit message下面:
Feature:Music play.
BugId:/
Description:Music play.
Change-Id: I3d087f04d9d94bfaa93b8609b988b300af537497
在一個project的每個branch中Change Id是唯一的。
- Patch Set
一個Patch Set就是一次commit,Gerrit會將其生成一個Branch暫存。Change中的每提交一個Patch Set表示這個Change的一個新的版本,自動覆蓋前一個Patch Set, 默認情況下,僅最後一個Patch Set是有意義的。Code Review通過時,也僅僅是最後一個Patch Set會合併到指定的branch中。
個人Git工作原則一
** 永遠是基於遠程庫的最新代碼工作,儘量每一步操作(特別是add/commit/push)都通過git pull --rebase獲取一下當前最新版本。**
根據以上原則,建議在將本地commit push到Gerrit之後,立馬reset掉,或者重新切換一個新的分支工作。
3.2.2 上傳一個新的patch set
當我們的commit被reviewer打回來時,我們可能需要修改並重新提交。
如果我們的代碼在本地分支已經reset掉,可以通過Gerrit頁面提供的Download方式獲取:
// fetch and checkout the change
// (checkout command copied from change screen)
$ git fetch ssh://[email protected]:29418/your_project refs/changes/45/545/9 && git checkout FETCH_HEAD
如果之前是通過切換分支方式工作的,可以重新切換回包含此commit的分支而無需執行上述命令,然後可以在此代碼基礎上進行修改,重新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界面添加相關reviewers.可以考慮使用自動添加reviewers的插件
3.2.4 提交Change
Change一般配置成只有在Code-Review +2 以及Verified +1 的情況下才可以Submit。
Submit時可能會有衝突,界面會提示“Cannot Merge”字樣,此時可以先嚐試Gerrit頁面提供的Rebase功能做一次Rebase操作,如果提示衝突,則需在本地解決衝突後重新提交一個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://[email protected]: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並行開發
Code Review需要時間,開發人員可以在此期間開發其他feature,這就產生了多feature並行開發的狀態。
爲了保證減少衝突和依賴,每一個feature都應該是在該feature自己的本地分支開發,且此分支是基於遠程分支(target branch)的當前HEAD的。 也就是基於遠程庫的最新代碼開發,而不應該依賴於code review中的某個、某些Change。
當然,如果必要,你也可以基於一個正在code review的Change開發新的feature,這樣會產生依賴,可以在Gerrit中該Change的頁面看到“Related Changes”。這就要求reviewer也需要關注這個依賴關係,調整review時序。
根據以往的使用經驗,強烈建議不要產生這種依賴,儘量使每一個Change提交都是無依賴的,避免Change的連環失敗導致各種解衝突的工作。
個人Git工作原則二
** 儘可能保證每一個Change的完整性以及獨立性,且越小越好。**
4, 進階功能
4.1 Web頁面代碼修改
Gerrit提供了直接在Web頁面修改我們的patch代碼的功能,這對於我們做一些小的問題修改(比如格式化問題,命名不對,多餘的空格等)非常方便。
Edit
點擊Edit後,該工具欄顯示如下:
toolbar
可以在此對patch的文件進行修改,刪除等。
如果想對文件中的某處進行編輯,點擊進入該文件的review界面:
page_edit
點擊編輯按鈕,進入編輯模式,編輯完save:
save
會在Change頁面看到,點擊Publish Edit按鈕,Gerrit會自動幫你生成一個包含剛剛修改的patch。
publish
patch
4.2 草稿箱功能
Gerrit可以作爲一個自己的Change草稿箱,我們可以將一些還未完成,或者還不想提交review的Change上傳至此處。一來可以作爲一個備份,另外在多人互相協助完成同一個功能,或是自己在多臺電腦(家裏、辦公室)上處理未完成的工作。
不同於提交一個正式Change的“refs/for/”協議,提交一個Change到草稿箱的協議方式爲“refs/drafts/”,如下:
$ git commit
$ git push origin HEAD:refs/drafts/luckyair
在Gerrit頁面的Drafts欄:
draft
草稿箱中的Change也可以很方便的轉換爲正式的Change,而無需重新用“refs/for/”來提交,點擊Publish按鈕轉換爲正式Change,也可以在此刪除此草稿。
publish draft