gerrit代码审核服务器的工作流和原理

来源:互联网 发布:掌上阅读软件下载 编辑:程序博客网 时间:2024/06/04 18:11

原文出处:http://www.worldhello.net/2010/11/10/2059.html

谷歌 Android 开源项目在 Git 的使用上有两个重要的创新,一个是为多版本库协同而引入的 repo,这在之前我们已经详细讨论过。另外一个重要的创新就是 Gerrit —— 代码审核服务器。Gerrit 为 Git 引入的代码审核是强制性的,就是说除非特别的授权设置,向 Git 版本库的推送(Push)必须要经过 Gerrit 服务器,修订必须经过代码审核的一套工作流之后,才可能经批准并纳入正式代码库中…


6.7   Gerrit 代码审核服务器

首先贡献者的代码通过 git 命令(或 repo 封装)推送到 Gerrit 管理下的 Git 版本库,推送的提交转化为一个一个的代码审核任务,审核任务可以通过 refs/changes/<change-id> 下的引用访问到。代码审核者可以通过 Web 界面查看审核任务、代码变更,通过 Web 界面做出通过代码审核或者打回等决定。测试者也可以通过 refs/changes/<change-id> 引用获取(fetch)修订对其进行测试,如果测试通过就可以将该评审任务设置为校验通过(verified)。最后经过了审核和校验的修订可以通过 Gerrit 界面中提交动作合并到版本库对应的分支中。

在 Android 项目的网站的代码贡献流程图更为详细的介绍了 Gerrit 代码审核服务器的工作流程。

代码审核工作流


6.7.1   Gerrit 的实现原理

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 中。其中nntask-id 和之前提交的评审任务的修订相同,m 则要人工选择一个新的修订号。

以上说起来很复杂,但是在实际操作中只要使用 repo 这一工具,就相对容易多了。

其余一切交给 Web

Gerrit 另外一个重要的组件就是 Web 服务器,通过 Web 服务器实现对整个评审工作流的控制。关于 Gerrit 工作流,参见在本章开头出现的 Gerrit 工作流程图。

感受一下 Gerrit 的魅力?直接访问 Android 项目的 Gerrit 网站: https://review.source.android.com/ 。



Android 项目代码审核网站

Android 项目的评审网站,匿名即可访问。点击菜单中的 “Merged” 显示了已经通过评审合并到代码库中的审核任务。下面的一个界面就是 Andorid 一个已经合并到代码库中的历史评审任务。

Android 项目的 16993 号评审

在该界面我们可以看到:


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*  5fb1e79b01166f51


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 新车尾箱坏了怎么办 放书的箱子烂了怎么办 车钥匙锁后备箱里怎么办 布的收纳箱有味怎么办 车漆清漆层掉了怎么办 副驾驶储物箱卡子断了怎么办 玛莎拉蒂车门打不开怎么办 新买的水杯漏水怎么办 泰迪小狗掉毛怎么办 手机jlc调用接口状态异常怎么办 进门和厕所对着怎么办 p过的照片有竖条怎么办 当照片p出竖条纹怎么办 月子里落下脚心怕风怕凉怎么办 鞋胶把手粘住了怎么办 凉鞋魔术贴长了怎么办 新买的狗一直叫怎么办 刚买的幼犬老叫怎么办 狗狗什么都不吃怎么办 新买的吊扇风小怎么办 夜市卖果汁没电怎么办 榻榻米太长2米45怎么办 木质桌子黏黏的怎么办 白色塑料桌子染色了怎么办 3dmax模型变透明了怎么办 刚养的兔子不吃怎么办 熊猫兔不吃下喝怎么办 熊猫兔感冒了一直打喷嚏怎么办 兔子后腿骨断了怎么办 兔子的腿肿了怎么办 仓鼠喝了牛奶该怎么办 宠物兔不吃不喝怎么办 兔子把木屑吃了怎么办? 小车司机碰瓷大车司机怎么办 在淘宝买到假的护肤品怎么办 淘宝购物发现是假的怎么办 电脑键盘灯不亮不能打字怎么办 海棠兔屁股有屎怎么办 大冒险告白被接受了怎么办剧透微博 大冒险被告白了怎么办 腐书网 大冒险告白被接受了怎么办 006