【保姆级教程】Ubuntu系统下快速安装Gerrit代码审阅工具

一、参考资料

官方文档:Gerrit Code Review for Git

烤鸭的gerrit使用总结-CSDN博客

烤鸭的gerrit使用总结-CSDN博客

最适合菜鸟的Gerrit搭建详解 - 简书

ubuntu 20.04LTS + gerrit + git + jenkins安装指南-CSDN博客

gerrit部署使用 - 良知犹存 - 博客园

Ubuntu 20.04 + Gerrit 3.4.0 + nginx 1.18.0 安装配置指南 - OSCHINA - 中文开源技术交流社区

Gerrit - 代码评审工具Gerrit简介与安装 - Anliven - 博客园

gerrit部署使用-CSDN博客

二、Gerrit相关介绍

1. Gerrit简介

Gerrit 是建立在 git 版本控制系统之上的,基于 web 的代码审核工具。Gerrit 是免费的,开源的,有一个可视化界面可供用户操作。主要解决的问题是代码审核。他在传统的源码工具管理协作流程中强制性引入代码审核机制,通过人工代码审核和自动化代码验证的方式,不符合要求的代码屏蔽在代码库之外,确保核心代码多人校验、多人互备和自动化构建核验。

2. Gerrit 和 Git 区别

  • Git 是一种版本控制系统;而 Gerrit 是一种基于 Web 的代码审查软件。
  • Git 用于代码的存储和版本控制;Gerrit 用于团队间相互审阅彼此修改后的程序代码,决定是否能够提交,退回或者继续修改。

3. Gerrit 和 Gitlab 区别

  • 开发风格
    gitlab 的特点是一个人维系一个分支。
    gerrit 的特点是一个团队维系一个分支。
  • 权限管理
    gitlab 可以根据需要创建 project,每个团队可以根据自己的需求管理自己的代码,方式更加的灵活。
    gerrit 比较单一,而且权限配置比较复杂,往往都是要联系管理员做出修改,每个团队很难做到对代码的个性化管理。
  • 代码评审
    gitlab 是以 merge request 作为一次 review,merge request 中可能包含多个 commit,如果 review 不通过也不需要发起另一次 merge request。
    gerrit 是以 commit 作为一次 review,由于 changeId 的存在,可以对一次commit反复的进行review。 如果task划分的粒度够细的话,并不会影响各个团队的review习惯。
  • 团队协作
    gitlab 可以选择公开代码,团队间可以看到互相的代码,有利于团队的协作。
    gerrit 由于权限控制问题,只能在权限范围内公开代码。
  • 信息共享
    gitlab 可以提供 issues,wiki 等功能方便开发者与使用者之间的沟通,并且 gitlab 可以无缝的与一些项目管理工具集成,比如:jira。
    gerrit 这个方面比较欠缺。

4. Gerrit工作流程

【Gerrit】Gerrit工作流程及使用手册-CSDN博客
Gerrit工作流程及使用手册-CSDN博客

如果你使用过 git,当我们 git add --> git commit --> git push 之后,你的代码会被直接提交到 repo,也就是代码仓库中。

Gerrit 的工作流程:

  1. 程序员编写代码。
  2. push 到 gerrit 服务器。
  3. 审核人员,在 web 页面进行代码的审核 (review),(可以单人审核,也可以邀请其他成员一同审核)。
  4. 审核通过 (approve) 之后。
  5. 提交(submit)到代码仓库(repo)中去。

在使用过程中,有两点需要特别注意下:

  1. 当进行 commit 时,必须要生成一个 Change-Id,否则,push 到 gerrit 服务器时,会收到一个错误提醒。
  2. 提交者不能直接把代码推到远程的 master 主线(或者其他远程分支)上去。这样就相当于越过了 gerrit了。 gerrit 必须依赖于一个 refs/for/* 的分支。假如我们远程只有一个 master 主线,那么只有当你的代码被提交到 refs/for/master 分支时,gerrit 才会知道,我收到了一个需要审核的代码推送,需要通知审核员来审核代码了。

三、安装Gerrit

Quickstart for Installing Gerrit on Linux

1. 安装Java

sudo apt-get update
sudo apt-get install openjdk-11-jdk
java -version

输出示例:

yoyo@yoyo:~/Downloads$ java -version
openjdk version "11.0.27" 2025-04-15
OpenJDK Runtime Environment (build 11.0.27+6-post-Ubuntu-0ubuntu120.04)
OpenJDK 64-Bit Server VM (build 11.0.27+6-post-Ubuntu-0ubuntu120.04, mixed mode, sharing)

2. 安装Git

sudo apt install git

3. 安装Nginx

Gerrit要求不能直接请求其端口,必须要使用反向代理才能正确登录。而我们知道Nginx的成功正在于其高效、轻量级以及 反向代理 ,虽然Apache也有反向代理的功能,但是如果你在安装Apache时没有开启,后续的开启过程要相对复杂一点,而Nginx就简单的多了。

sudo apt-get update
sudo apt-get install nginx

卸载Nginx:

sudo apt-get remove nginx nginx-common # 卸载删除除了配置文件以外的所有文件。
sudo apt-get purge nginx nginx-common # 卸载所有东东,包括删除配置文件。
sudo apt-get autoremove # 在上面命令结束后执行,主要是卸载删除Nginx的不再被使用的依赖包。
sudo apt-get remove nginx-full nginx-common #卸载删除两个主要的包。

4. 下载Gerrit

下载链接:https://www.gerritcodereview.com/#download,官网直接下载最新版本(不推荐)。

在这里插入图片描述

也可以使用wget工具命令行下载 Gerrit Code Review - Releases

sudo wget https://gerrit-releases.storage.googleapis.com/gerrit-3.12.0.war

5. 解压Gerrti

cd ${GERRIT_SITE}
sudo unzip gerrit-3.12.0.war -d ${GERRIT_SITE}

6. 创建Gerrit目录

export GERRIT_SITE=~/gerrit_site

sudo mkdir ${GERRIT_SITE}  # 创建一个目录,准备安装gerrit
sudo chown -R $USER:$USER ${GERRIT_SITE}

7. 安装Gerrit

java -jar ~/Downloads/gerrit-3.12.0.war init -d ${GERRIT_SITE}

安装过程中,选择HTTP认证模式:

Authentication method          [openid/?]: HTTP
Get username from custom HTTP header [y/N]? y

安装过程中,设置 ip/port

Listen on address              [*]: 
Listen on port                 [8081]: 
Canonical URL                  [http://ubuntu/]: http://localhost:8081

安装插件(推荐):

*** Plugins
*** 

Installing plugins.
Install plugin codemirror-editor version v3.8.10 [y/N]? y
Installed codemirror-editor v3.8.10
Install plugin commit-message-length-validator version v3.8.10 [y/N]? y
Installed commit-message-length-validator v3.8.10
Install plugin delete-project version v3.8.10 [y/N]? y
Installed delete-project v3.8.10
Install plugin download-commands version v3.8.10 [y/N]? y
Installed download-commands v3.8.10
Install plugin gitiles version v3.8.10 [y/N]? y
Installed gitiles v3.8.10
Install plugin hooks version v3.8.10 [y/N]? y
Installed hooks v3.8.10
Install plugin plugin-manager version v3.8.10 [y/N]? y
Installed plugin-manager v3.8.10
Install plugin replication version v3.8.10 [y/N]? y
Installed replication v3.8.10
Install plugin reviewnotes version v3.8.10 [y/N]? y
Installed reviewnotes v3.8.10
Install plugin singleusergroup version v3.8.10 [y/N]? y
Installed singleusergroup v3.8.10
Install plugin webhooks version v3.8.10 [y/N]? y
Installed webhooks v3.8.10
Initializing plugins.

后续可以通过配置文件($GERRIT_SITE/etc/gerrit.config)来更新配置。

输出示例:

yoyo@yoyo:~$ java -jar ~/Downloads/gerrit-3.8.10.war init -d ${GERRIT_SITE}
Using secure store: com.google.gerrit.server.securestore.DefaultSecureStore
[2025-06-30 02:45:09,709] [main] INFO  com.google.gerrit.server.config.GerritServerConfigProvider : No ~/gerrit_site/etc/gerrit.config; assuming defaults

*** Gerrit Code Review 3.8.10
*** 

Create '~/gerrit_site' [Y/n]? Y

*** Git Repositories
*** 

Location of Git repositories   [git]: git

*** JGit Configuration
*** 

Auto-configured "receive.autogc = false" to disable auto-gc after git-receive-pack.

*** Index
*** 

Type                           [lucene]: 

*** User Authentication
*** 

Authentication method          [openid/?]: HTTP
Get username from custom HTTP header [y/N]? y
Username HTTP header           [SM_USER]: 
SSO logout URL                 : 
Enable signed push support     [y/N]? 
Use case insensitive usernames [Y/n]? 

*** Review Labels
*** 

Install Verified label         [y/N]? y

*** Email Delivery
*** 

SMTP server hostname           [localhost]: 
SMTP server port               [(default)]: 
SMTP encryption                [none/?]: 
SMTP username                  : 

*** Container Process
*** 

Run as                         [yoyo]:   
Java runtime                   [/usr/lib/jvm/java-11-openjdk-amd64]: 
Copy gerrit-3.8.10.war to ~/gerrit_site/bin/gerrit.war [Y/n]? 
Copying gerrit-3.8.10.war to ~/gerrit_site/bin/gerrit.war

*** SSH Daemon
*** 

Listen on address              [*]: 
Listen on port                 [29418]: 
Generating SSH host key ... rsa... ed25519... ecdsa 256... ecdsa 384... ecdsa 521... done

*** HTTP Daemon
*** 

Behind reverse proxy           [y/N]? y
Proxy uses SSL (https://)      [y/N]? 
Subdirectory on proxy server   [/]: 
Listen on address              [*]: 
Listen on port                 [8081]: 
Canonical URL                  [http://ubuntu/]: http://localhost:8081       

*** Cache
*** 


*** Plugins
*** 

Installing plugins.
Install plugin codemirror-editor version v3.8.10 [y/N]? y
Installed codemirror-editor v3.8.10
Install plugin commit-message-length-validator version v3.8.10 [y/N]? y
Installed commit-message-length-validator v3.8.10
Install plugin delete-project version v3.8.10 [y/N]? y
Installed delete-project v3.8.10
Install plugin download-commands version v3.8.10 [y/N]? y
Installed download-commands v3.8.10
Install plugin gitiles version v3.8.10 [y/N]? y
Installed gitiles v3.8.10
Install plugin hooks version v3.8.10 [y/N]? y
Installed hooks v3.8.10
Install plugin plugin-manager version v3.8.10 [y/N]? y
Installed plugin-manager v3.8.10
Install plugin replication version v3.8.10 [y/N]? y
Installed replication v3.8.10
Install plugin reviewnotes version v3.8.10 [y/N]? y
Installed reviewnotes v3.8.10
Install plugin singleusergroup version v3.8.10 [y/N]? y
Installed singleusergroup v3.8.10
Install plugin webhooks version v3.8.10 [y/N]? y
Installed webhooks v3.8.10
Initializing plugins.

============================================================================
Welcome to the Gerrit community

Find more information on the homepage: https://www.gerritcodereview.com
Discuss Gerrit on the mailing list: https://groups.google.com/g/repo-discuss
============================================================================
Initialized ~/gerrit_site
Init complete, reindexing accounts,changes,groups,projects with: reindex --site-path ~/gerrit_site --threads 1 --index accounts --index changes --index groups --index projectsReindexed 0 documents in accounts index in 0.0s (0.0/s)
Index accounts in version 12 is ready
Reindexing groups:      100% (2/2)
Reindexed 2 documents in groups index in 0.2s (8.7/s)
Index groups in version 9 is ready
Reindexing changes: Slicing projects: 100% (2/2), done    
Reindexed 0 documents in changes index in 0.0s (0.0/s)
Index changes in version 82 is ready
Reindexing projects:    100% (2/2)
Reindexed 2 documents in projects index in 0.1s (23.5/s)
Index projects in version 5 is ready
Executing ~/gerrit_site/bin/gerrit.sh start
Starting Gerrit Code Review: WARNING: Could not adjust Gerrit's process for the kernel's out-of-memory killer.
         This may be caused by ~/gerrit_site/bin/gerrit.sh not being run as root.
         Consider changing the OOM score adjustment manually for Gerrit's PID=77690 with e.g.:
         echo '-1000' | sudo tee /proc/77690/oom_score_adj
OK
Waiting for server on ubuntu:80 ... OK
Please open the following URL in the browser: http://ubuntu/#/admin/projects/

8. 修改gerrit.sh

sudo vi ${GERRIT_SITE}/bin/gerrit.sh

添加一行:

GERRIT_SITE=~/gerrit_site

9. 修改gerrit.config

主配置文件$GERRIT_SITE/etc/gerrit.config

  • Gerrit Server监听 8081端口
  • 认证方式为 HTTP
  • 8081是默认的Gerrit Web端口。
  • 29418是默认的Gerrit SSH端口。

完整配置:

[gerrit]
	basePath = git
	canonicalWebUrl = http://localhost:8081/
	serverId = a6bdcde1-f741-4c7e-86fe-a62cf6ae4c23
[container]
	javaOptions = "-Dflogger.backend_factory=com.google.common.flogger.backend.log4j.Log4jBackendFactory#getInstance"
	javaOptions = "-Dflogger.logging_context=com.google.gerrit.server.logging.LoggingContext#getInstance"
	user = root
	javaHome = /usr/lib/jvm/java-11-openjdk-amd64
[index]
	type = lucene
[auth]
	type = HTTP  
	# 如果使用的是标准HTTP认证
  	# 可能不需要指定httpHeader,但如果需要可以尝试以下选项之一:
  	#httpHeader = Authorization  
  	#httpHeader = REMOTE_USER
	#httpHeader = SM_USER
	#userNameCaseInsensitive = true  
[receive]
	enableSignedPush = false
[sendemail]
	smtpServer = localhost
[sshd]
	listenAddress = *:29418
[httpd]
	listenUrl = proxy-http://*:8081/
[cache]
	directory = cache

10. 设置Nginx反向代理

添加关于gerrit的配置:/etc/nginx/conf.d/gerrit.conf

添加以下内容:

server {
    listen *:8088;
    server_name localhost;
    allow all;
    deny all;

    location / {    
    	auth_basic "Welcome to Gerrit Code Review Site!";
    	auth_basic_user_file ~/gerrit_site/etc/gerrit.password;
    	
        proxy_pass http://localhost:8081/;
        
        #proxy_set_header X-Real-IP $remote_addr;
        #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-For $remote_addr;
        #proxy_set_header X-Forwarded-Proto $scheme;    	
        #proxy_set_header SM_USER $remote_user;
        #proxy_set_header Host $host;
        
        # 明确将REMOTE_USER设置为认证用户名
	#proxy_set_header REMOTE_USER $remote_user;
	    
	# 同时传递多种认证头格式
	#proxy_set_header Authorization $http_authorization;
	#proxy_pass_header Authorization;  # 明确传递Authorization头
	
	# 设置其他常用头部
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
	
	proxy_set_header SM_USER $remote_user;  
	proxy_set_header X-Forwarded-User $remote_user;
	    
	# 确保原始请求头不被修改
	proxy_pass_request_headers on;
    }
    
    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }
}

解释说明:

  • listen:Nginx代理服务器监听的端口。
  • auth_basic:用于登录时弹出验证对话框所显示的内容。
  • auth_basic_user_file:HTTP验证用户名和密码是否匹配的文件,请参考后文【注册用户认证】。
  • location 部分:表示当用户访问8088端口时,Nginx直接将此请求代理到8081端口上,也就是”反向代理“。
    • 8081是默认的Gerrit Web端口。
    • 8088是Nginx反向代理端口,也即浏览器访问的端口。

11. 启动Gerrit

# 启动
sudo ${GERRIT_SITE}/bin/gerrit.sh start

# 停止
sudo ${GERRIT_SITE}/bin/gerrit.sh stop

# 重启
sudo ${GERRIT_SITE}/bin/gerrit.sh restart

# 查看Gerrit状态
sudo netstat -ltpn | grep -i gerrit

查看Gerrit状态:

yoyo@yoyo:~/gerrit_site/logs$ sudo netstat -ltpn | grep -i gerrit
[sudo] password for yoyo: 
Sorry, try again.
[sudo] password for yoyo: 
tcp6       0      0 :::29418                :::*                    LISTEN      105670/GerritCodeRe 
tcp6       0      0 :::8081                 :::*                    LISTEN      105670/GerritCodeRe

12. 启动Nginx

# nginx服务相关的指令
ps aux | grep nginx       # 查看nginx进程
service nginx start       # 启动Nginx服务
service nginx stop        # 停止Nginx服务
service nginx restart     # 重启Nginx服务
service nginx status      # 查看Nginx服务的状态

# 或者执行
sudo systemctl start nginx.service
sudo systemctl stop nginx.service
sudo systemctl restart nginx.service
sudo systemctl status nginx.service

# 也可以到nginx目录下直接操作
sudo /etc/init.d/nginx start      # 启动
sudo /etc/init.d/nginx stop       # 关闭
sudo /etc/init.d/nginx restart    # 重启
sudo /etc/init.d/nginx status     # 查看状态

service nginx reload      # 在Nginx服务启动的状态下,热加载gerrit.conf配置文件

启动之后可以使用工具查看一下自己配置的端口有没有正常工作: sudo netstat -ltpn

ps $(fuser 8088/tcp)这个工具可以直接查看有没有占据这个端口的进程

13. htpasswd注册用户认证

一文搞懂 htpasswd:基础身份验证的密码管理工具-CSDN博客

我们需要用apach的 htpasswd 工具来新建这个文件,虽然我使用了nginx代替apache做反向代理,但仍然需要apache。

安装 apache htpasswd

sudo apt-get install apache2-utils

创建用户:第一个注册的用户默认成了管理员,所以Gerrit安装完毕第一件事要做的就是注册或者登陆,以便初始化管理员账户。

# 创建第一个用户admin,同时会生成一个gerrit.password文件
htpasswd -c ${GERRIT_SITE}/etc/gerrit.password admin      

# 在gerrit.password增加用户用 -m
htpasswd -m ${GERRIT_SITE}/etc/gerrit.password master

# 在gerrit.password增加用户用 -m
htpasswd -m ${GERRIT_SITE}/etc/gerrit.password reviewer

输出示例:

yoyo@yoyo:~/gerrit_site/bin$ htpasswd -c ${GERRIT_SITE}/etc/gerrit.password admin
New password: 
Re-type new password: 
Adding password for user admin
yoyo@yoyo:~/gerrit_site/bin$ htpasswd -m ${GERRIT_SITE}/etc/gerrit.password master
New password: 
Re-type new password: 
Adding password for user master

14. 登录Gerrit

Basic HTTP认证模式不支持 Sign Out
需要先 Sign Out 退出账号,关闭浏览器后再登录,才能出现HTTP验证密码对话框。

输入下面链接,就可以登录到gerrit页面。

http://localhost:8088

四、FAQ

Q:java.lang.UnsupportedClassVersionError: Main has been compiled by a more recent version of the Java Runtime (class file version 65.0), this version of the Java Runtime only recognizes class file versions up to 55.0

yoyo@yoyo:~$ java -jar ~/Downloads/gerrit-3.12.0.war init -d ${GERRIT_SITE}
Error: LinkageError occurred while loading main class Main
	java.lang.UnsupportedClassVersionError: Main has been compiled by a more recent version of the Java Runtime (class file version 65.0), this version of the Java Runtime only recognizes class file versions up to 55.0

错误原因:java版本与Gerrrit版本不兼容,导致Gerrrit安装失败。

解决方法:安装低版本的Gerrit。

Q: The HTTP server did not provide the username in the Authorization header when it forwarded the request to Gerrit Code Review.

在这里插入图片描述

错误原因:Gerrit采用HTTP认证,如果未安装Nginx代理服务器,则无法访问Gerrit服务。

解决方法:安装Nginx代理服务器。

Q:Starting Gerrit Code Review: start-stop-daemon: matching only on non-root pidfile ~/gerrit_site/logs/gerrit.pid is insecure

yoyo@yoyo:~/gerrit_site/etc$ sudo ${GERRIT_SITE}/bin/gerrit.sh start
Starting Gerrit Code Review: start-stop-daemon: matching only on non-root pidfile ~/gerrit_site/logs/gerrit.pid is insecure

查看日志:

[2025-06-30T03:39:47.846-07:00] [main] ERROR com.google.gerrit.pgm.Daemon : Unable to start daemon
com.google.inject.ProvisionException: Unable to provision, see the following errors:

1) [Guice/ErrorInjectingConstructor]: LockObtainFailedException: Lock held by another program: ~/gerrit_site/index/changes_0082/open/write.lock
  at LuceneChangeIndex.<init>(LuceneChangeIndex.java:139)
  while locating ChangeIndex annotated with @UniqueAnnotations$Internal(value=7)

解决方法

(1)关闭Gerrit:

sudo ${GERRIT_SITE}/bin/gerrit.sh stop

(2)杀死Gerrit进程:

ps aux | grep gerrit

kill -9 <PID>

(3)重启Gerrit:

yoyo@yoyo:~/gerrit_site/bin$ sudo ./gerrit.sh restart
Stopping Gerrit Code Review: No process in pidfile '~/gerrit_site/logs/gerrit.pid' found running; none killed.
OK
Starting Gerrit Code Review: OK

Q:无法Sign out

Gerrit使用HTTP认证-不能退出登录 - 简书

错误原因:用gerrit+HTTP认证,通过web登陆后,点击右上角的 Sign Out 无法登出。要么是依然保持登陆的状态,要么就是直接出错,这是正常的。

解决方法

(1)直接关闭浏览器,重新登录。

(2)如果你的浏览器保存了账号密码,需要清除缓存,再重新登录。

Q:error: failed to push some refs to

yoyo@yoyo:~/share/driver/hello_world$ git push ssh://admin@localhost:29418/hello_world *:*
Enumerating objects: 1525, done.
Counting objects: 100% (1525/1525), done.
Delta compression using up to 8 threads
Compressing objects: 100% (1365/1365), done.
Writing objects: 100% (1525/1525), 216.40 MiB | 6.95 MiB/s, done.
Total 1525 (delta 298), reused 0 (delta 0)
remote: Resolving deltas: 100% (298/298)
remote: error: branch refs/heads/master:
remote: You need 'Create' rights to create new references.
remote: User: admin
remote: Contact an administrator to fix the permissions
remote: Processing changes: refs: 1, done    
To ssh://localhost:29418/hello_world
 ! [rejected]        dev -> dev (fetch first)
 ! [remote rejected] master -> master (prohibited by Gerrit: not permitted: create)
error: failed to push some refs to 'ssh://admin@localhost:29418/hello_world'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花花少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值