介绍#
关于Gerrit#
Gerrit,一种开放源代码的代码审查软件,使用网页界面。利用网页浏览器,同一个团队的程序员,可以相互审阅彼此修改后的代码,决定是否能够提交,退回或是继续修改。它使用版本控制系统Git作为底层。
定位#
理论上Git虽然是一个分布式版本管理系统,不需要中心代码库就能相互同步数据。而在实际的操作过程中,为了方便一个团队的多名开发人员通常需要指定一个确定的代码库用于提交和相互同步代码。所以我们的代码管理一般使用如下结构:
在引入Gerrit代码审核机制后,我们的代码提交和同步的方式发生了变化:

工作流程#
首先贡献者的代码通过 git 命令推送到 Gerrit 管理下的 Git 版本库,推送的提交转化为一个一个的代码审核任务,审核任务可以通过 refs/changes/

用户登录#
首先打开主页 http://192.168.51.201:81
主页会提示登录:

其中用户名与密码皆与邮箱账号名相同,如:
username :wanghh
password : 111111powershell登录后的界面如下:

简单入手#
克隆代码仓库#
进行代码修改、提交审查,显然第一步是要从远程代码库中克隆一份代码。Gerrit服务提供了HTTP和SSH两种服务(使用SSH协议需要配置本机密钥)供大家从远程服务器获取代码,获取方式可在项目基本信息页面查看。

其中 clone 命令有两种类型:
1. 命令含 commit-msg hook#
git clone "http://wanghh%40fdmtek.com@192.168.52.46:8088/a/gerrit-base" \
&& (cd "gerrit-base" && mkdir -p `git rev-parse --git-dir`/hooks/ \
&& curl -Lo `git rev-parse --git-dir`/hooks/commit-msg http://192.168.52.46:8088/tools/hooks/commit-msg \
&& chmod +x `git rev-parse --git-dir`/hooks/commit-msg)bash功能:
- 克隆仓库:
首先,通过
git clone命令从 Gerrit 服务器克隆gerrit-base仓库。 - 设置
commit-msg hook:- 进入克隆的 Git 仓库目录
gerrit-base。 - 创建一个 Git Hooks 的目录:
GIT_DIR/hooks/。(GIT_DIR是 Git 的.git文件夹路径,由git rev-parse --git-dir获取)。 - 下载
commit-msghook:使用curl从服务器地址http://192.168.52.46:8088/tools/hooks/commit-msg获取文件。 - 添加执行权限:对下载的
commit-msg文件运行chmod +x。
- 进入克隆的 Git 仓库目录
作用:
commit-msg hook 是 Gerrit 为 Git 提供的一种工具:
- 检查提交的消息是否符合 Gerrit 的要求。
- 在提交消息中自动添加 Change-Id,这是 Gerrit 用于跟踪代码变更的标识符。
- 没有该 hook 时,手动提交可能会报错或不符合 Gerrit 的提交规范。
这个命令适用于需要 Gerrit Change-Id 参与代码审查的用户,例如提交代码到 Gerrit 时必须满足其 Change-Id 要求。
2. 命令不含 commit-msg hook#
git clone "http://wanghh%40fdmtek.com@192.168.52.46:8088/a/gerrit-base"bash功能:
- 此命令只是简单地克隆了指定的仓库
gerrit-base。 - 克隆后的仓库没有额外设置
commit-msg hook,意味着使用默认的 Git 操作。
作用:
- 适合仅用于拉取代码或进行简单的本地修改,而不提交代码到 Gerrit。
- 如果用户计划把修改提交到 Gerrit,则可能会缺少 Change-Id,因此 Gerrit 后续可能拒绝提交。
HTTP 使用需要申请 Token 用于验证#

同时可以顺便验证一下邮箱(重要!)

➜ git_test git clone "http://wanghh%40fdmtek.com@192.168.52.46:8088/a/gerrit-base" && (cd "gerrit-base" && mkdir -p `git rev-parse --git-dir`/hooks/ && curl -Lo `git rev-parse --git-dir`/hooks/commit-msg http://192.168.52.46:8088/tools/hooks/commit-msg && chmod +x `git rev-parse --git-dir`/hooks/commit-msg)
Cloning into 'gerrit-base'...
Password for 'http://wanghh%40fdmtek.com@192.168.52.46:8088':
remote: Counting objects: 2, done
remote: Finding sources: 100% (2/2)
Receiving objects: 100% (2/2), 197 bytes | 197.00 KiB/s, done.
remote: Total 2 (delta 0), reused 0 (delta 0)
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 3127 100 3127 0 0 1737k 0 --:--:-- --:--:-- --:--:-- 3053k
➜ git_test cd gerrit-base
➜ gerrit-base git:(master) git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree cleanbash仓库 clone 完成之后就可以进行后续的操作:
➜ gerrit-base git:(master) ✗ git add .
➜ gerrit-base git:(master) ✗ git commit -m "v0.0.1"
[master 8d921fc] v0.0.1
1 file changed, 1 insertion(+)
create mode 100644 test.txt
➜ gerrit-base git:(master) git push
Password for 'http://wanghh%40fdmtek.com@192.168.52.46:8088':
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Writing objects: 100% (3/3), 274 bytes | 274.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
remote: error: branch refs/heads/master:
remote: Push to refs/for/master to create a review, or get 'Push' rights to update the branch.
remote: User: wanghh@fdmtek.com
remote: Contact an administrator to fix the permissions
remote: Processing changes: refs: 1, done
To http://192.168.52.46:8088/a/gerrit-base
! [remote rejected] master -> master (prohibited by Gerrit: not permitted: update)
error: failed to push some refs to 'http://192.168.52.46:8088/a/gerrit-base'bash此时需要的密码依然是之前生成的 Token,但是可以发现 Push 操作被拒绝了。这是因为仓库中的权限没有开放,并且通常无法直接 push 到 master,需要首先 push 到 gerrit 的分支上,如 refs/for/master


此时,我们就可以进行提交了
➜ gerrit-base git:(master) git push origin HEAD:refs/for/master
Password for 'http://wanghh%40fdmtek.com@192.168.52.46:8088':
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Writing objects: 100% (3/3), 274 bytes | 274.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Processing changes: refs: 1, new: 1, done
remote:
remote: SUCCESS
remote:
remote: http://192.168.52.46:8088/c/gerrit-base/+/1 v0.0.1 [NEW]
remote:
To http://192.168.52.46:8088/a/gerrit-base
* [new reference] HEAD -> refs/for/masterbash提交成功之后就可以在gerrit中看到变化:


可以看到当前是不满足 submit 条件的。需要进行 Review 与 Verify。
审查代码#
默认情况下项目的所有者、管理员能够指定代码的审核人。指定审核人后,Gerrit会给审核人发送邮件提醒有审核任务。
审核代码的流程:
- 浏览代码增量,并给出注释;
- 浏览完成所有代码,并给出综合评价和评分(-2, -1, 0, 1, 2)。只有打分>2,才能允许merge到目标分支。
这个时候,我们想起允哥说有空的时候就可以想起他:

此时,电脑另一端的允哥也就收到了干活的消息:

允哥打开 gerrit 后,也看到新的 commit

随后允哥觉得小伙子写的很不错!

但是这时高老爷也过来看了一下,说小伙子菜还得多练啊

返工修改#
根据上面Gerrit流程图,当代码审核、确认未通过或合并的过程中出现冲突,这个时候就需要返工修改后再提交。
返工流程有三步:
- 获取未通过的代码到本地工作目录;
- 修改代码;
- 再提交审核。
修改好代码之后我们再次提交
➜ gerrit-base git:(master) ✗ git add .
➜ gerrit-base git:(master) ✗ git commit --amend
[master 2a84938] v0.0.1
Date: Fri Jan 9 14:14:47 2026 +0800
1 file changed, 3 insertions(+)
create mode 100644 test.txt
// push patch set
➜ gerrit-base git:(master) git push origin HEAD:refs/for/master
Password for 'http://wanghh%40fdmtek.com@192.168.52.46:8088':
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Writing objects: 100% (3/3), 301 bytes | 301.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Processing changes: refs: 1, updated: 1, done
remote:
remote: SUCCESS
remote:
remote: http://192.168.52.46:8088/c/gerrit-base/+/1 v0.0.1
remote:
remote: The following approvals got outdated and were removed:
remote: * Code-Review+1 by guoy@fdmtek.com
remote: * Code-Review+1 by wanghh@fdmtek.com
remote:
remote:
To http://192.168.52.46:8088/a/gerrit-base
* [new reference] HEAD -> refs/for/masterbash修改后的提交,change-id不会发生变化,而仅仅是patch-id加1。

这一次,高老爷也满意了。至此,我们完成了代码的 Review。
验证修改#
新提交的修改,如果已经通过代码审核,下一步流程则是代码验证。验证之前需要代码测试人员先将修改获取到本地,然后对代码进行测试。代码测试后,则投票对本次修改做出评价。

提交修改#
当代码成功通过Review和Verified后,此时这段修改后的代码片段就可以合并到主分支里面去了。
这时候,高老爷动了动小手:

代码这时真正被同步到了 master 分支中。

查看 官方文档 ↗ 了解更多
另:
Gerrit 的 HTTP 验证通常依赖外部的反向代理来处理用户的认证,客户端通过浏览器发送 HTTP basic authentication 的头部信息来完成验证。因此:
- 用户的登录状态由浏览器缓存的 Basic Authentication 凭据维持,不存储在 Gerrit 中。
- 用户点击
Sign out后,Gerrit 本身无法清除浏览器上缓存的凭据。 - 此外,现代浏览器的 HTTP Basic Auth 无法通过 JS 或页面行为主动触发清理,退出登录变得较为困难。
**即:*浏览器缓存了 Basic Authentication 凭证,*即使点击了 Sign out,浏览器依然用之前缓存的凭据重新发送认证请求,导致用户无法登出。
基于较新的火狐内核支持特定形式的 URL 处理,因此通过反代的配置修改能够清除缓存的 HTTP Basic Authentication 会话,解决此问题。但是基于 chromium 内核的浏览器可能会依然存在这个问题,如果你拒绝使用火狐且坚持需要退出用户登录的话,请自行清理浏览器缓存记录。