Contents
  1. 1. gerrit工作流程
  2. 2. 管理员配置
    1. 2.1. profile
    2. 2.2. Preferences
    3. 2.3. Watched Projects
    4. 2.4. Contact Information
    5. 2.5. SSH Public Keys
      1. 2.5.1. 生成公私钥对
      2. 2.5.2. 找到公钥文件
    6. 2.6. Groups
  3. 3. 示例
    1. 3.1. 管理员设置SSH
    2. 3.2. 添加普通成员
    3. 3.3. 修改用户所在组
    4. 3.4. 新建和修改项目
    5. 3.5. test3用户clone工程
    6. 3.6. 提交
    7. 3.7. 管理员审查
      1. 3.7.1. 事件处理
  4. 4. SourceTree
    1. 4.1. 设置自定义push
  5. 5. 致谢&参考文文章
Update at 2019-08-04

今天偶然看了下图片的流量,发现这篇讲Gerrit的流量好高,果然一看这篇blog的阅读量已经好几万了。为了不误导大家,我还是做下更新:
本人已经很久不使用Gerrit了,现在用GitLab,界面非常美观,使用方法也很简单,而且也能满足之前的代码审核的要求。所以大家也都转去GitLab吧。
关于GitLab的搭建和使用网上应该有很多介绍,这里就不做过多的介绍,我这里有一篇GitBook和GitLab搭建使用的文章,如果要使用GitLab的CI功能,可以参考一下http://lipeng1667.github.io/2019/01/15/public-doc-with-gitlab-ci-writing-with-gitbook/


上一篇文章中,我们介绍了如何安装和正确配置gerrit,相对于gerrit的使用,它的安装真的算简单的了。
gerrit的流程、权限控制其实对于初次接触的同学们来说,确实有点复杂。我希望这篇文章过后,我们能对gerrit的流程有一个大致的了解。
这篇文章将用一个真实的例子,演示一下gerrit的管理员,普通项目成员是如何协同完成项目管理工作的。

这篇文章首先会大致讲解下gerrit的工作流程;然后介绍管理员的相关配置工作,包括设置SSH密钥验证,添加新成员;接下来会用一个示例演示普通成员push一个commit之后,代码审核员是如何进行审核的;最后介绍一下如何使用sourceTree上传代码到gerrit服务器。

提醒:
这篇文章需要一定的git基础,如果你还不熟悉git,请先学习下关于git的相关知识。
这篇文章中的所有操作不再需要登录到gerrit服务器上去了,因为所有的操作都是在管理员或者普通成员的电脑上完成的,至于管理员对组员的操作,也可以在管理员自己的电脑上通过SSH连接到gerrit服务器上完成。

gerrit工作流程

好不容易在google上找了一篇相对简单明了的介绍gerrit工作流程的图:



使用过git的同学,都知道,当我们git add --> git commit --> git push 之后,你的代码会被直接提交到repo,也就是代码仓库中,就是图中橘红色箭头指示的那样。

那么gerrit就是上图中的那只鸟,普通成员的代码是被先push到gerrit服务器上,然后由代码审核人员,就是左上角的integrator在web页面进行代码的审核(review),可以单人审核,也可以邀请其他成员一同审核,当代码审核通过(approve)之后,这次代码才会被提交(submit)到代码仓库(repo)中去。

无论有新的代码提交待审核,代码审核通过或被拒绝,代码提交者(Contributor)和所有的相关代码审核人员(Integrator)都会收到邮件提醒。
gerrit还有自动测试的功能,和主线有冲突或者测试不通过的代码,是会被直接拒绝掉的,这个功能似乎就是右下角那个老头(Jenkins)的任务。

整个流程就是这样。 在使用过程中,有两点需要特别注意下:

  1. 当进行commit时,必须要生成一个Change-Id,否则,push到gerrit服务器时,会收到一个错误提醒。
  2. 提交者不能直接把代码推到远程的master主线(或者其他远程分支)上去。这样就相当于越过了gerrit了。 gerrit必须依赖于一个refs/for/*的分支。

    假如我们远程只有一个master主线,那么只有当你的代码被提交到refs/for/master分支时,gerrit才会知道,我收到了一个需要审核的代码推送,需要通知审核员来审核代码了。
    当审核通过之后,gerrit会自动将这条分支合并到master主线上,然后邮件通知相关成员,master分支有更新,需要的成员再去pull就好了。而且这条refs/for/master分支,是透明的,也就是说普通成员其实是不需要知道这条线的,如果你正确配置了sourceTree,你也应该是看不到这条线的。

这两点很重要!!这两点很重要!!这两点很重要!!

这两点在稍后的示例中,我们会依次介绍。

管理员配置

在上一篇文章的最后,我们做为管理员,初次登录到了gerrit的web页面中,接下来还有很多内容需要设置一下。我们依次来看看吧。

profile



初次登录时,Full Name 和 Email Address 字段都是空的,待会我们会一一设置。没有设置之前,右上角显示的用户名称也是admin

Preferences



Preferences页面用于配置gerrit的web页面,我一般把时间格式改成习惯的24小时制,同时确保Email Nofification处于开启状态,这个默认就是开启的;然后在Show Change Number In Changes Tables打上勾,这样能清楚地看到每个审核的编号,邮件里面显示的也是这个编号。

Watched Projects

这里有必要先说一下gerrit的两个默认项目:

我们点击左上方的菜单栏 Projects –> List,就能看到两个默认的项目All-ProjectsAll-Users,这两个工程是两个基础的工程,我们新建的工程默认都是继承自All-Projects的权限。关于权限部分我们在后面的章节详细介绍。



所以在Watched Projects菜单中,就是当前用户要监听的项目,当这些项目发生变化时,你会收到邮件提醒,如果你选择了All-Projects,那么就意味着你要监听所有的工程,因为所有工程都会默认继承自All-Projects



注意,后面的那些选项,勾选了某一项,就表示仅仅给当前项发送邮件提醒,保险期间,我们就全部勾上就好了。

Contact Information



这里是当前账号的配置,你可以在这里把full-name填写完全,这样右上角也会同步更新你刚设置好的名称。

注意这里的Preferred Email有两种设置方法:

  1. 如果你的邮件服务器配置完成了(不清楚如何配置的同学请参见上一篇文章),可以点击Register New Email,你就会收到一封确认邮件,确认之后就能设置好了。
  2. 通过SSH在命令行中进行配置,通过命令行进行配置是最方便快捷,也是最优先推荐的方法。

不过因为SSH命令行的方式需要配置SSH公钥,所以我们这里先留空,一会通过命令行来配置。

SSH Public Keys



这里需要把你的公钥内容拷贝出来,然后粘贴到对话框中。我简单演示下如何操作。

生成公私钥对

如果你之前有使用过git,那你一定已经生成了公私钥对,可以直接跳过这个步骤。
在命令行中输入下面的内容:

1
$ ssh-keygen -t rsa

然后会提示你输入一个密码,用来访问公私钥,可以直接回车表示不加密码。接下来就会自动帮你创建好一对公私钥了。

找到公钥文件

默认公私钥的是放置在~/.ssh目录下的,默认的名称是id_rsaid_rsa.pub。其中.pub文件就是公钥,私钥你自己需要保存好。我们来看下我的.ssh文件夹中的内容



  • config是ssh的配置文件,稍后我们会演示通过管理员ssh连接到gerrit服务器时,会在来看这个文件
  • lipeng和lipeng.pub分别是我的私钥和公钥

我们要做的,就是把公钥的内容拷贝出来,然后粘贴到页面上去。
注意拷贝时,要从RSA开始拷贝,如果格式不对,页面上会有提示。
还有一点要说明的是,这些都是在你想要作为管理员账号的机器上操作完成,对我来说,我的macbook就是管理员要使用的电脑。

Groups



最后来看一下gerrit的分组。图片里面是gerrit默认的几个分组,我们需要知道的是Administrator就是管理员分组,Anonymous Users指的是所有添加到gerrit数据库中的成员都默认加入的一个组。之后我们还可以建立新的分组,加入新的成员等等。

示例

接下来我们来做一个演示,看看一个新的成员是如何被添加到gerrit服务器中,然后他们又是如何协同工作的。
这里一共涉及到两个角色,一个是管理员,一个是普通成员。

管理员设置SSH

在之前的文章中我们提到过,gerrit自带的H2数据库就完全够用了,对成员的管理,邮件添加等操作,均可以通过SSH来完成。那第一步我们就来看一下管理员如何才能远程SSH到gerrit服务器。

首先确保在之前,已经成功把你的公钥添加到了web页面账户中。
接下来,需要修改之前~/.ssh/文件夹下面的config文件,我们拿我的config文件做为示例,做个讲解。

我们还是先进入到~/.ssh/文件夹中



然后查看一下config文件: vim config



我们看到这里面有两个Host部分,我们重点来看第2个Host部分,这个是我们新建的,用于连接到gerrit服务器的配置。

照猫画虎,对于我们之前建立在192.168.1.100的gerrit服务器来说,你的Host配置可能如下:

1
2
3
4
5
Host gerrit
HostName "192.168.1.100"
User "admin"
IndentityFile "~/.ssh/id_rsa"
port 29418

User要和我们在gerrit服务器上注册的名称保持一致( 不是 full-name),认证文件注意要和公钥对应的私钥文件,端口要填写gerrit服务的端口号,这里是默认的29418

配置完config文件,我们就可以SSH到gerrit了,我们来尝试一下吧:



我们在管理员的机器上,输入ssh gerrit -l admin命令,就可以得到gerrit服务器的响应,只不过因为我们禁用了shell,所以连接很快断开了,没有关系,这样证明做为管理员,已经可以通过命令行对gerrit服务器进行一系列的操作了。

添加普通成员

在管理员添加新的组员之前,我们需要先在普通成员的机器上生成ssh的公私钥,这里方便描述,我们把这个普通成员命名为test3。

在test3的电脑命令行中,生成利用ssh-keygen命令,生成公私钥。



我们就使用默认的id_rsa命名好了。

接下来,test3成员需要把id_rsa.pub公钥发送给管理员,这样管理员才能正常把test3添加到gerrit用户组中。
我们假设管理员将test3的pub公钥放到了~/home目录下,也就是说,在管理员的电脑上,test3的公钥存放在~/home/id_rsa.pub文件,当然我们也可以重新把它命名为test3.pub,方便演示我这里就不做更名处理了,

接下来,管理员在命令行中输入如下的命令来完成添加普通成员的操作。注意: 这个命令很强大很方便,可以一步到位地把成员的的名称,全名,邮箱以及ssh公钥认证全部设置好。

1
$ cat ~/home/id_rsa.pub | ssh gerrit gerrit create-account --full-name test3 --email test3@microwu.com --ssh-key - test3

接下来我们来详细看一下这个命令:

  • | 符号把这个命令分成了两部分,第一部分的cat ~/home/id_rsa.pub表示把test3的公钥内容读入到输入流中
  • ssh gerrit是我们之前在~/.ssh/config中配置好的gerrit服务器地址
  • 又接着一个gerrit表示通过ssh中输入gerrit命令来进行相关操作
  • create-account 表示要新建用户。注意,新建的用户名写在最后面,中间是其他参数
  • full-name 就如同页面中的全名,我们这里命名为test3
  • email表示该用户的email地址,我们填入 test3@microwu.com
  • ssh-key - 注意,最后的- 表示从输入流中读取ssh的公钥内容,也就是 | 符号之前我们读入的test3用户公钥内容
  • 最后面加上我们要create的用户名称

这个命令执行完之后,管理员就把test3用户加入到了gerrit用户组中,并且设置了他的全称,邮件以及公钥文件,是不是一步到位,非常方便??

这里我们回过头来,在管理员首次登陆web页面进行修改配置的时候,我们说过,管理员的邮箱可以通过命令行来设置,是的,同样通过ssh命令行:

1
$ ssh gerrit gerrit set-account --add-email admin@microwu.com admin

这个命令就表示为我们的admin用户添加email`admin@microwu.com`。执行完这个命令,再回到web界面上的用户设置界面,看看是不是管理员的email已经被设置好了??

修改用户所在组

接下来我们看一下怎样修改test3用户所在的组吧。我们知道他已经出在Anonymous Users组中了,那我们想要新建一个组,就叫test_user吧,我们来看一下



我们在gerrit页面的顶部,点击People –> list, 看一下默认的两个分组,AdministratorNon-interactive Users,这两个分组我们都能从字面上理解是什么意思。我们注意到Anonymous Users这个分组并没有显示在页面,因为它是匿名的嘛,所有的用户自动添加到这个分组中了。



选择Create New Group,输入我们要添加的新的分组 test_user



新的分组中,我们看到管理员的账号被自动添加了进来



我们在Add搜索栏中输入test,就会自动显示出来管理员之前在命令行中创建的test3用户,看到full-name和email了吧,都已经添加完成了!
test3用户已经添加到了test_user分组中了。

新建和修改项目

用同样的方法,我们来新建一个项目吧



点击Project,然后Create New Project, 创建一个名为test2的项目吧。



可以通过点击project名称,进入到工程的详细设置界面。



点击顶部菜单栏中的Access,来设置这个项目的权限吧。
我们可以看到这个项目已经有了个默认的继承自All-Projects的权限,关于默认的权限这里不做多的介绍,想要深入学习的同学可以点击进去看一下。

修改权限的时候慎重,不要直接修改All-Projects组的权限,因为这个是所有项目的依赖权限组,修改了以后,所有的项目权限都会跟着发生变化。



我们点击Edit按钮来修改这个项目的权限



我们把Reference改成refs/*,表示所有的refs下的分支
然后选择read项目



接着筛选不同的分组,并且赋予不同的权限。

  • 我们把Anonymous Users分组中的用户设置为DENY
  • 把我们刚建立好的,并且添加了test3用户的test_user分组权限设置为ALLOW

这样,当前的工程就只能被test_user组内的用户所访问,其他组的用户均无法访问了!

test3用户clone工程

接下来我们来到test3用户的电脑上,下拉刚刚创建的test2工程



在命令行执行下面的命令,就可以把test2工程给clone下来了

1
$ git clone ssh://test3@192.168.1.100:29418/test2.git

对比下,会发现我们的目录中多了一个名为test2的文件夹,这个就是我们的工程了!



注意如果从ssh方式clone下来的工程,里面是自带了hooks文件夹的,这个文件夹很重要!!如果不是用ssh://方式克隆下来的,还没有这个文件夹,需要我们自己mkdir

我们直接新建一个test.md文件,来尝试着往远程提交。

注意: 前方会出现很多错误,耐心一步一步来

提交

首先我们通过下面两个命令首先commit到本地仓库:

1
2
$ git add test.md
$ git commit



在commit的时候,发现提交者的名称和email都是错误的,我们需要先配置成我们当前的test3用户,以及对应的email

1
2
$ git config user.name test3
$ git config user.email test3@microwu.com



通过git config --list来查看一下当前git仓库的配置,发现已经把用户名和密码正确设置了。

接下来我们继续git commit来提交到本地



我们把这次提交命名为commit_1,然后我们通过git push命令来推送



发现推送失败了,提示的错误是:

You are not allowed to perform this operation
[remote rejected] master -> master (prohibited by Gerrit)

Gerrit拒绝了我们直接提交到master的推送!

这就是我们在文章开头提到的问题,我们需要push到refs/for/master那条线上!!

那怎么办呢??
我们在命令行写入下面的命令:

1
$ git config remote.origin.push refs/heads/*:refs/for/*

这行命令的意思是,当执行push命令时,将会推送到refs/for/当前head所在的分支上。



我们设置了push命令之后,重新进行push,结果又报错了。。
这次的错误是:

missing Change-Id in commit message footer

这个是提到的第2个问题,commit一定要有Change-Id
然后我们看到了命令行中给了我们提示,我们可以从hooks文件中拷贝commit-msg文件下来,这样commit时,会自动帮我们生成Change-Id.



我们可以看一下 git rev-parse --git-dir就是指向的当前git配置的文件,就是.git文件夹
所以我们直接用scp命令从gerrit服务器上拉取当前用户的hooks文件。

1
$ scp -p -P 29418 test3@192.168.1.100:hooks/commit-msg .git/hooks/

然后我们重新push发现一样的错误,因为我们还停留在上次commit,上次的commit是没有生成Change-Id的!



没有关系,我们回退一下,然后重新提交。
回退命令是先用git log找到上一次的commit id, 然后用git reset --hard 找到的id命令回退

这次我们终于提交成功了,可以看到提交到的分支是refs/for/master

管理员审查

接下来我们回到管理员的web页面,会发现,test3用户刚提交的那条已经在页面中了
点击顶部的My --> Watched Changes



因为之前我们已经监听了All-Projects,而test2工程又是默认继承自All-Projects的,所以我们就可以收到了,如果当前管理员没有监听All-Projects,就需要手动把test2项目加进来,否则是不会在watched页面看到这条推送提醒的。

与此同时,我们会收到来自gerrit@microwu.com发送来的邮件了:



事件处理

我们通过点击commit_1可以进入到当前事件的详情页面:



可以在页面中看到我们生成的Change-Id,以及我们新添加的文件test.md,点击以后可以看到每个文件的详情。
注意屏幕中间的两个按钮:

  • Reply 表示对这次事件的回应,里面可以有5个选项,表示当前审查人员对这个事件的打分:-2,-1,0,+1,+2, +2表示直接同意,1表示我同意了,需要别的人员来一起审核
  • Code-Review+2 相当于直接打+2分



我们还可以通过点击右边的小人,来添加新的审核人员



reply之后,如果分数够了2分,就可以直接submit到主线上去了



合并了之后,可以在 My --> Changes 中看到我们的审核历史



到这里,一个完整的从普通项目成员提交,到代码审核人员检查的全过程,就结束了。

SourceTree

SourceTree是git的可视化工具,也是比较流行的git工具,通过sourceTree我们一样可以commit,push等,而且更方便直观地看到项目的历史等等。

在上面的示例中,我们都是通过命令行来完成git的相关操作的,那通过soureTree,我们同样需要注意那两点:

  1. commit时要有Change-Id
  2. push一定要到refs/for/master分支上

这里还需要额外注意一点:

  • 如果我们是通过soureTree工具clone项目,而不是通过ssh://方式来clone,那么工程中的.git文件夹中是没有hooks文件夹的,需要我们手动去文件夹中创建

我们在管理员的视角从gerrit服务器上拉取之前的test2工程吧:





  • Source URL中填入gerrit:test2.git。 因为我们之前已经在.ssh/config文件中设置好了名为gerrit的HOST所以这里就可以简写了



可以看到test3用户提交的commit_1,因为已经通过审核了,所以,就合并到master中了

我们到当前的目录中,看一下.git文件夹,确实是没有hooks文件夹的



我们通过scp gerrit:hooks/commit-msg hooks/命令来拉取commit-msg文件



同时通过git config remote.origin.push refs/heads/*:refs/for/*命令来设置push命令

设置自定义push

虽然我们设置好了push命令到远程的refs/for/*目录,但是如果我们直接用SourceTree中的push功能,我们会发现直接给我们在远程新建了一个refs/for/*分支,而且gerrit也没有审核事件触发,这是因为sourceTree的push应该是有它自己的一些配置,所以这里我们需要自定义push事件,来完成将代码推送到正确的分支上。



我们进入SourceTree的配置页面



点击Custom Actions,然后输入命令的名字: push to gerrit

  • Script to run: 指的是要执行的文件,我们这里把git的可执行文件目录放进来,如果是windows请自行找到该目录
  • Parameters 就直接写入push,表示执行的是push命令



最后当我们要通过推送到gerrit服务器时,在当前的分支上,右键,然后点击Custom Actions,再选择我们刚创建的push to gerrit动作,就实现了推送到gerrit服务器的功能!!

好了,到这里,关于gerrit的所有内容都介绍完了!!!

致谢&参考文文章

这里特别感谢烤鸭的gerrit使用总结,基本上我都是在这篇blog上一点一点摸索出来的,不过作者写的总结时间有点远了,所以我在他的上面做了一些总结和新增。

其余参考文件:

Contents
  1. 1. gerrit工作流程
  2. 2. 管理员配置
    1. 2.1. profile
    2. 2.2. Preferences
    3. 2.3. Watched Projects
    4. 2.4. Contact Information
    5. 2.5. SSH Public Keys
      1. 2.5.1. 生成公私钥对
      2. 2.5.2. 找到公钥文件
    6. 2.6. Groups
  3. 3. 示例
    1. 3.1. 管理员设置SSH
    2. 3.2. 添加普通成员
    3. 3.3. 修改用户所在组
    4. 3.4. 新建和修改项目
    5. 3.5. test3用户clone工程
    6. 3.6. 提交
    7. 3.7. 管理员审查
      1. 3.7.1. 事件处理
  4. 4. SourceTree
    1. 4.1. 设置自定义push
  5. 5. 致谢&参考文文章