SSH 協議的 Git 服務器
Gerrit 自己基於 SSH 協議實現了一套 Git 服務器,這樣就能夠對 Git 數據推送進行更爲精確的控制,爲強制審覈的實現創建了基礎。 Gerrit 提供的 Git 服務的端口並不是標準的 22 端口,缺省是 29418 端口。能夠訪問 Gerrit 的 Web 界面獲得這個端口。對 Android 項目的代碼審覈服務器,訪問
https://review.source.android.com/ssh_info
就能夠查看到 Git 服務的服務器域名和開放的端口。下面咱們用 curl 命令查看網頁的輸出。
$ curl -L -k http://review.source.android.com/ssh_info
review.source.android.com 29418
特殊引用 refs/for/<branch-name> 和 refs/changes/nn/<task-id>/m
Gerrit 的 Git 服務器,禁止用戶向
refs/heads命名空間下的引用執行推送(除非特別的受權),即不容許用戶直接向分支進行提交。爲了開發者可以向 Git 服務器提交修訂,Gerrit 的 Git 服務器只容許用戶向特殊的引用
refs/for/<branch-name>
下執行推送,其中
<branch-name>
即爲開發者的工做分支。向
refs/for/<branch-name>
命名空間下推送並不會在其中建立引用,而是爲新的提交分配一個 ID,稱爲 task-id ,併爲該 task-id 的訪問創建以下格式的引用
refs/changes/nn/<task-id>/m
,其中:
- task-id 爲 Gerrit 爲評審任務順序分配的全局惟一的號碼。
- nn 爲 task-id 的後兩位數,位數不足用零補齊。即 nn 爲 task-id 除以 100 的餘數。
- m 爲修訂號,該 task-id 的首次提交修訂號爲 1,若是該修訂被打回,從新提交修訂號會自增。
Git 庫的鉤子腳本 hooks/commit-msg
爲了保證已經提交審覈的修訂經過審覈入庫後,被別的分支 cherry-pick 後再推送至服務器時不會產生新的重複的評審任務,Gerrit 設計了一套方法,即要求每一個提交包含惟一的 Change-Id,這個 Change-Id 由於出如今日誌中,當執行 cherry-pick 時也會保持,Gerrit 一旦發現新的提交包含了已經處理過的
Change-Id
,就再也不爲該修訂建立新的評審任務和 task-id,而直接將提交入庫。 爲了實現 Git 提交中包含惟一的 Change-Id,Gerrit 提供了一個鉤子腳本,放在開發者本地 Git 庫中(hooks/commit-msg)。這個鉤子腳本在用戶提交時自動在提交說明中建立以 "Change-Id: " 及包含
git hash-object
命令產生的哈希值的惟一標識。當 Gerrit 獲取到用戶向refs/for/<branch-name>
推送的提交中包含 "Change-Id: I..." 的變動 ID,若是該 Change-Id 以前沒有見過,會建立一個新的評審任務並分配新的 task-id,並在 Gerrit 的數據庫中保存 Change-Id 和 Task-Id 的關聯。 若是當用戶的提交由於某種緣由被要求打回重作,開發者修改以後從新推送到 Gerrit 時就要注意在提交說明中使用相同的 「Change-Id」 (使用 --amend 提交便可保持提交說明),以避免建立新的評審任務,還要在推送時將當前分支推送到
refs/changes/nn/task-id/m中。其中
nn
和
task-id
和以前提交的評審任務的修訂相同,m 則要人工選擇一個新的修訂號。 以上提及來很複雜,可是在實際操做中只要使用 repo 這一工具,就相對容易多了。
其他一切交給 Web
Gerrit 另一個重要的組件就是 Web 服務器,經過 Web 服務器實現對整個評審工做流的控制。關於 Gerrit 工做流,參見在本章開頭出現的 Gerrit 工做流程圖。 感覺一下 Gerrit 的魅力?直接訪問 Android 項目的 Gerrit 網站:
https://review.source.android.com/
。
Android 項目代碼審覈網站
Android 項目的評審網站,匿名便可訪問。點擊菜單中的 「Merged」 顯示了已經經過評審合併到代碼庫中的審覈任務。下面的一個界面就是 Andorid 一個已經合併到代碼庫中的歷史評審任務。
Android 項目的 16993 號評審 android
在該界面咱們能夠看到:
- URL 中顯示的評審任務編號爲 16993。
- 該評審任務的 Change-Id 以字母 I 開頭,包含了一個惟一的 40 位 SHA1 哈希。
- 整個評審任務有三我的參與,一我的進行了檢查(verify),兩我的進行了代碼審覈。
- 該評審任務的狀態爲已合併:「merged」。
- 該評審任務總共包含兩個補丁集: Patch set 1 和 Patch set 2。
- 補丁集的下載方法是: repo download platform/sdk 16993/2 。
若是使用 repo 命令獲取補丁集是很是方便的,由於封裝後的 repo 屏蔽掉了 Gerrit 的一些實現細節,例如補丁集在 Git 庫中的存在位置。如前所述,補丁集實際保存在 `refs/changes` 命名空間下。使用 `git ls-remote` 命令,從 Gerrit 維護的代碼庫中咱們能夠看到補丁集對應的引用名稱。
$ git ls-remote ssh://review.source.android.com:29418/platform/sdk refs/changes/93/16993*
5fb1e79b01166f5192f11c5f509cf51f06ab023d refs/changes/93/16993/1
d342ef5b41f07c0202bc26e2bfff745b7c86d5a7 refs/changes/93/16993/2
接下來咱們就來介紹一下 Gerrit 服務器的部署和使用方法。