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 服务器的部署和使用方法。