Gerrit VS Gitlab

一、Gerrit 简介

第一次入职的时候,看到 Gerrit 的我是一脸懵逼,这是个什么上古的玩意,界面交互这么丑…因为,在之前公司都是使用类似
GitLab 这种版本控制平台,初次使用或多或少有些抵触,后面几天通过了解其工作流程,大概对它有了个基本的认识。

引用 wiki 百科的介绍 Gerrit 和 GitLab

Gerrit,一种开放源代码的代码审查软件,使用网页界面。利用网页浏览器,同一个团队的软件开发者,可以相互审阅彼此修改后的代码,决定是否能够提交,回退或是继续修改。它使用版本控制系统Git作为底层。

GitLab, 是由 GitLab Inc.开发,一款基于 Git 的完全集成的软件开发平台(fully 集成软件 development platform)。另外,GitLab 且具有wiki以及在线编辑、issue跟踪功能、CI/CD 等功能。

基于笔者个人的理解,Gerrit 是一个建立在 Git 版本控制之上的,是基于 Web 端的一款代码审查工具,这一点要区别于 GitLab。
一旦团队当中有新人加入,那么使用 Gerrit 来确保代码的质量就很有必要了。

参考文档

二、Gerrit vs GitLab

这里主要以流行性、开发风格、权限管理、代码评审、信息共享这几点进行展开说明

1. 流行性

(数据统计于2021-04-22)直接上数据,毕竟量化的结果才具有说服力,群众的眼睛是雪亮的。
在这里插入图片描述

在这里插入图片描述

2.开发风格

  • GitLab 特点是一个人维护一个分支
  • Gerrit 则是多人共同维护一个分支(主要应用于大型、持续迭代,具有版本控制的项目)

3. 权限控制

GitLab 通过组权限可以统一分配仓库权限,成员权限分为以下几种:

  • Guest 仅具有访问仓库权限,提交 issue,发表评论
  • Reporter 可以 clone 代码,但是不能提交
  • Developer 仓库开发人员,具有代码 push 权限
  • Master 仓库管理员
  • Owner 仓库的拥有者

Gerrit 中的权限控制是基于群组的,每个用户有一个或者多个群组,访问权限被赋予到这些群组。

因此,Gerrit 的权限是不能赋予给个人用户的,群组主要分为以下几个:

4. 代码评审

GitLab 采用的是 MR(merge request) 的方式作为一次 review。 MR 中包含了一个或多个 commit 记录,如果当前的 MR 被 reject,
下次提交依然可以使用该 MR 进行提交。

在这里插入图片描述

Gerrit 则是以 commit 作为一次 review,由于每一次 commit 都会产生一个唯一的 Change-Id,因此,我们就可以反复修改同一个 commit,
对其进行 code review。
Gerrit 的代码审核流程可以直接参考下图,很直观,具体操作流程,请参考第四章节。
在这里插入图片描述

参考文档

5.信息共享

GitLab 提供了 issues,wiki(不太好用)等功能方便开发者与使用者之间可能很好的交流互动,并且 GitLab 集成了项目管理工具 Jira。
Gerrit 这方面比较欠缺,毕竟这不是它擅长的功能。

三、Gerrit 基础配置

为了使本机能够与远端仓库建立连接,首先就需要在本机初始化个人凭证,然后将个人凭证存放到远端仓库。由于需要使用 SSH 的方式进行连接,因此需要先生成 SSH 密钥。

1.生成 ssh 公钥

$ ssh-keygen -t rsa -C "<公司注册的邮箱地址>"
# 或者可以指定文件名 -f <文件名>
$ ssh-keygen -f test   -C "test key"

如果询问是否需要输入密码,一般不需要,敲两次回车即可。

2.查看密钥是否生成成功
输入如下指令即可查看,控制台中会出现两个 id_rsa* 文件,如果没有说明凉了…

$ ll ~/.ssh

在这里插入图片描述

3.复制 id_rsa.pub 公钥内容
执行下面的指令,将输出的内容进行复制

$ cat ~/.ssh/id_rsa.pub 

在这里插入图片描述

4.存储到 gerrit 远端仓库
将上一步复制的内容,粘贴到 gerrit 仓库。

gerrit 仓库地址:https://gerrit.zhenguanyu.com/settings/#SSHKeys

操作步骤:

【进入仓库】-【settings】-【SSH Keys】-【New SSH Key】-【ADD NEW KEY】
在这里插入图片描述

5.检测 SSH 通道连接是否正常

$ ssh -p 29418 gerrit.zhenguanyu.com

在这里插入图片描述

补充:如果出现 ssh 登录,permission denied(publickey)
在这里插入图片描述

请点击查看解决方法:Gerrit 常见问题汇总#5.ssh permission denied(publickey)

参考文档

四、Gerrit 最佳实践

1. 新建项目

这一步很简单,在 gerrit repos 中进行创建:https://gerrit.xxx.com/admin/repos
执行如下操作:

【CREATE NEW】-【填写仓库信息】-【CREATE】进行创建。
在这里插入图片描述

2. 拉取远端仓库代码

创建空的仓库后,copy 下图第一个指令,然后在本地执行。
在这里插入图片描述

其中,commit-msg hook 可以帮助我们自动生成 Change-Id,具体原因后续会讲。

执行下面语句,检测 Commit-msg hook 是否下载成功

# 在项目根目录下,执行下面指令
$  cat .git/hooks/commit-msg
  1. 提交 commit(重要)
    注意:提交代码前,必须先修改本地 git 配置
# 在项目根目录下,执行下面指令
$ vim .git/config

在文件末尾,追加如下配置

解释一下含义:即当本地代码 push 到 remote review 分支上时,会自动追加对应的 reviewer 人(此处的 reviewer为 xxx)

[remote "review"]
	url = <远端仓库地址>
	push = <reviewer 邮箱地址,通常是xxx的邮箱>

下面是一个例子:

[remote "review"]
	url =  http://gerrit.zhenguanyu.com/yangxinbj-test-proj
	push = <re>HEAD:refs/for/master%r=panqh@yuanfudao.com

最终配置如下图:
在这里插入图片描述

产生一次新的提交

# 新建文件,产生一次变更
$ echo "hello world" > README.md
$ git add .
$ git commit -m 'feat: create md file.'

注意:gerrit 的提交信息的 footer 中必须包含一段 Change-Id,这就要求我们每次提交内容必须插入一段 Change-Id
幸好,我们可以利用 git hooks 中的 commit-msg hook 特性,实现当 commit 提交时,会在提交内容 footer 处,自动追加一行 Change-Id。

4. 新建分支

注意:这里和 gitlab 不同,本地新建的分支不能直接被推送到远端,而是需要先将该分支对应的 HEAD:refs/for/<本地分支名> 推送到远端。

这里和 gitlab 不同,需要先在远端创建分支,然后本地进行 pull 操作。
Gerrit上对应项目的access的refs/*的“push”权限可以运行推送代码和分支到gerrit上;“Create Reference”权限运行创建分支;
在这里插入图片描述

远端创建分支:【仓库】-【Branches】-【CREATE NEW】-【填写分支信息】-【CREATE】
如下图所示,远程仓库创建了一个 test 分支
在这里插入图片描述

然后,本地执行如下指令

$ git pull origin HEAD:refs/for/<远程分支名>
# 本示例中,执行以下语句
$ git switch -c test # 切换到 test 分支
$ git pull origin HEAD:refs/for/test 

5. 推送分支代码(重要)

先介绍一下 git push 的用法

$ git push <remote_name> <local_branch>:<remote_branch>
# 例如
$ git push origin HEAD:refs/for/test
# push 简化写法
$ git push origin master
# push 完整写法
$ git push origin master:master
  • origin: 远程主机名
  • HEAD: 本地当前分支名
  • refs/for/test: 远程分支名

产生一个新的本地提交代码

$ echo "hello world" >> README.md
$ git add .
$ git commit -m 'ADD: create md file'

最后,提交本地代码到远程仓库

$ git push orign HEAD:refs/for/<要提交的分支名>
# 本示例中,执行以下语句
$ git push origin HEAD:refs/for/test

tips: 每次 push 都要加一个 HEAD:refs/for/ 前缀,如果觉得这种写法很麻烦,有个简化配置:

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

注意:每次 push 之后的记录,都必须先经过 CR 才能正常合入到代码仓库的。

6. 提交 comment & reply comment

当代码 push 到远程时,需要让其他同事对我们的代码进行审核,只有审核通过的代码才能允许被合入。
如果将其他同事审核的建议修复完后,可以点击 CR 进行提交
在这里插入图片描述

点击 reply 发表评论,当 reviewer 评论完成之后,对当前的代码进行评分:

在这里插入图片描述

不同分数代表不同的态度,只有 +2 才能允许被提交

  • -2:不应该提交
  • -1: 语气稍弱一些
  • 0:无所谓
  • +1:看起来不错,但还是需要其他人再确认一下
  • +2:应该可以提交

提交完成之后,状态会发生改变,这是再次点击 【SUBMIT】同意合并本次提交

在这里插入图片描述

点击提交之后,当前的状态改变为 【Merged】说明本次提交已经成功合入

在这里插入图片描述

  1. git commit --amend(常用)
    在上一个步骤中,如果看到其他同事给了修改建议(不可能 bug free),那就需要对原有代码进行修改。

此时有两种方式,可以对已提交的内容进行修改:

  • 修改完成之后,产生一个新的 commit。
  • 在原有的提交历史上,进行修改。好处是不会产生新的 commit ,方便追踪代码变更历史。
$ echo "append2" >> README.md  # 追加一句修改
$ git add .
$ git commit --amend # 执行后进行编辑窗口,按 :wq 保存并且修改

8. rebase commit (常用)

小测试:

将以下三次提交中小写的字母,改成大写

$ echo "a" >> README.md  # 追加一句修改 a
$ git add .
$ git commit -m 'ADD: char a'
$ echo "b" >> README.md  # 追加一句修改 b
$ git add .
$ git commit -m 'ADD: char b'
$ echo "c" >> README.md  # 追加一句修改 c
$ git add .
$ git commit -m 'ADD: char c'

然后,执行下面的指令

$ git rebase -i # 进入交互式的界面
# 如果没有成功进入
$ git branch --set-upstream-to=origin/<remote_branch> <local_branch> 

同步提交代码

# 推送提交内容到远端仓库
$ git push origin HEAD:refs/for/test
# merge 代码之后,同步更新代码
$ git pull --rebase

8. 分支合并

当我们从 master 创建一个新的分支进行开发后,如果当前 master 分支,没有其他人进行过 merge 操作,我们将开发分支合并到 master 分支后,会触发 fast-forward (快进)合并逻辑。

此时,并不会产生一次新的 merge commit!!!

如果使用 gerrit 的话,当合并到 master 分支推送到远端代码,就会出现 no changes 的错误。

解决方案:

在进行 merge 操作的时候,执行下面语句即可:

# --no-ff 说明此时不进行 fast-forward 操作
# --log 会将合并日志完整打印
$ git merge hotfix/xxx-error --no-ff --log

在这里插入图片描述

参考文档

五、Gerrit 常见问题

1. 为什么 Gerrit 需要 Change-ID

首先,需要对一次代码审查任务进行定义:通常认为对一次完整任务的功能实现或者 BUG 修复进行的审查,如果审查的代码是半成品,那么审查得到的结论是不可靠的。
那么,有必要对一次代码审查任务进行标识,因此,提出了使用 Change-Id 来标识一次完整的代码提交。
Change-Id 实际上就是一串以 I 开头的字符串。形如步骤 4 中的图。

下面这张图很简洁的介绍了 gerrit 扮演的角色,主要充当的是代码审核管理的角色。

在这里插入图片描述

2.为什么Gerrit 需要推送 HEAD:refs/for/*

https://cloud.tencent.com/developer/ask/73945

3.Merge 冲突时 Change-Id 不在最后一行

首先了解一下 git pull 指令,git pull 其实就是 git fetch 和 git merge FETCH_HEAD 的简写。
当执行 git pull 拉取远程仓库代码时,会进行 merge 操作,此时会触发 git hook 自动在 message 的
footer 下追加一行 Change-Id,然后又会自动追加一个冲突文件名。

解决方法:

# 修改提交的消息内容
$ git commit --amend

参考文档

  • 7
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值