NotePublic/Software/Application/Gerrit/Gerrit_的日常使用.md

8.0 KiB
Raw Blame History

Gerrit 的日常使用

1 Gerrit 是什么

Gerrit 实际上一个 Git 服务器,它为在其服务器上托管的 Git 仓库提供一系列权限控制,以及一个用来做 Code Review 是 Web 前台页面。当然,其主要功能就是用来做 Code Review。

2 Gerrit 用户配置

2.1 Email 激活

Gerrit 账户的设置界面点击“Contact Information”进入 Email Register 页面,输入自己的邮箱账户(此邮箱需要与自己的 Git 配置一致)。可以配置多个 Email 账号。

2.2 SSH key 配置

$ssh-keygen -t rsa
$cat ~/.ssh/id_rsa.pub

Copy id_rsa.pub 的内容,在 Gerrit 账户的设置页面 “SSH Public Key” 中加入即可。

3 Gerrit 日常使用

3.1 获取代码库

登录 Gerrit 后在 Projects-->List, 选择相应工程 your_project进入该工程的 General 界面。

选中“clone with commit-msg hook”和“SSH”:

git clone ssh://your_account@review.xxxxx.com:29418/your_project && scp -p -P 29418 your_account@review.xxxxx.com:hooks/commit-msg cic-android/.git/hooks/

拷贝以上命令在自己本地 Git 命令行窗口执行即可拉取库代码。

3.2 Gerrit 工作流程

3.2.1 上传一个 commit

Gerrit 相对 Git 提供了一个特有的命名空间“refs/for/”用来定义我们的提交上传到哪个 branch且可以用来区分我们的 commit 是提交到 Gerrit 进行审核还是直接提交到 Git 仓库,格式如下:

refs/for/<target-branch>

Push 一个 Commit 到 Gerrit:

$git commit
$git push origin HEAD:refs/for/master

直接 Push 一个 commit 到 Git 仓库:(我们默认配置成不允许)

$git commit
$git push origin HEAD:master

当我们的 commit Push 到 Gerrit 等待 review 时Gerrit 会将此 commit 保存在一个名为“refs/changes/xx/yy/zz”的一个暂存 branch 中。
其中 zz 为这个 commit 的 patch set 号yy 是 change 号xx 是 change 号的后两位。

例如我们工程中的这个大明同学的提交:

http://review.xxxxx.com:9090/#/c/545/

一共提交了 9 次 patch那么第 9 个 patch 就保存在一个名为“refs/changes/45/545/9”的 branch 中。

可以通过 Gerrit 页面中该 commit 右上角的 Download 按钮验证,比如说我们选择“Cherry Pick”, 命令如下:

git fetch ssh://your_account@review.xxxxx.com:29418/your_project refs/changes/45/545/9 && git cherry-pick FETCH_HEAD

在此,有必要说下几个概念,以便理解:

  • Change

一个 Change 包含一个 Change-Id这个 Id 就是通过我们拉取代码库的时候所拷贝的 hookshooks/commit-msg自动生成的。 包含一个或多个 Patch Set以及诸如 OwnerProjectTarget branch,Comments 等信息。

  • Change-Id

Change-Id 是一串 SHA-1 字符串。有 hooks 自动生成在我们的 commit message

  • Patch Set

一个 Patch Set 就是一次 commitGerrit 会将其生成一个 Branch 暂存。Change 中的每提交一个 Patch Set 表示这个 Change 的一个新的版本,自动覆盖前一个 Patch Set 默认情况下,仅最后一个 Patch Set 是有意义的。Code Review 通过时,也仅仅是最后一个 Patch Set会合并到指定的branch中。

个人 Git 工作原则一
** 永远是基于远程库的最新代码工作,尽量每一步操作(特别是 add/commit/push都通过 git pull --rebase 获取一下当前最新版本。**

根据以上原则,建议在将本地 commit push 到 Gerrit 之后,立马 reset 掉,或者重新切换一个新的分支工作。

3.2.2 上传一个新的patch set

当我们的 commit 被 reviewer 打回来时,我们可能需要修改并重新提交。

如果我们的代码在本地分支已经 reset 掉,可以通过 Gerrit 页面提供的 Download 方式获取:

# fetch and checkout the change
# (checkout command copied from change screen)
$git fetch ssh://your_account@review.xxxxx.com:29418/your_project refs/changes/45/545/9 && git checkout FETCH_HEAD

如果之前是通过切换分支方式工作的,可以重新切换回包含此 commit 的分支而无需执行上述命令,然后可以在此代码基础上进行修改,重新 addamend commit:

# rework the change
$git add <path-of-reworked-file>
...

# amend commit
$git commit --amend

# push patch set
$git push origin HEAD:refs/for/master

3.2.3 添加 Reviewers

在 Change 界面添加相关 reviewers.可以考虑使用自动添加 reviewers 的插件

3.2.4 提交 Change

Change 一般配置成只有在 Code-Review +2 以及 Verified +1 的情况下才可以 Submit。

Submit 时可能会有冲突,界面会提示 “Cannot Merge” 字样,此时可以先尝试 Gerrit 页面提供的 Rebase 功能做一次 Rebase 操作,如果提示冲突,则需在本地解决冲突后重新提交一个 Patch Set 到该 Change 上。

本地 Rebase 的一种流程:

# update the remote tracking branches
$git fetch

# fetch and checkout the change
# (checkout command copied from change screen)
$git fetch ssh://your_account@review.xxxxx.com:29418/your_project refs/changes/74/67374/2 && git checkout FETCH_HEAD

# do the rebase
$git rebase origin/master

# resolve conflicts if needed and stage the conflict resolution
...
$git add <path-of-file-with-conflicts-resolved>

# continue the rebase
$git rebase --continue

# push the commit with the conflict resolution as new patch set
$git push origin HEAD:refs/for/master

3.3 多 Feature 并行开发

Code Review 需要时间,开发人员可以在此期间开发其他 feature这就产生了多 feature 并行开发的状态。

为了保证减少冲突和依赖,每一个 feature 都应该是在该 feature 自己的本地分支开发且此分支是基于远程分支target branch的当前 HEAD 的。 也就是基于远程库的最新代码开发,而不应该依赖于 code review 中的某个、某些 Change。

当然,如果必要,你也可以基于一个正在 code review 的 Change 开发新的 feature这样会产生依赖可以在 Gerrit 中该 Change 的页面看到“Related Changes”。这就要求 reviewer 也需要关注这个依赖关系,调整 review 时序。

根据以往的使用经验,强烈建议不要产生这种依赖,尽量使每一个 Change 提交都是无依赖的,避免 Change 的连环失败导致各种解冲突的工作。

个人 Git 工作原则二
** 尽可能保证每一个 Change 的完整性以及独立性,且越小越好。**

4 进阶功能

4.1 Web页面代码修改

Gerrit 提供了直接在 Web 页面修改我们的 patch 代码的功能,这对于我们做一些小的问题修改(比如格式化问题,命名不对,多余的空格等)非常方便。

点击 Edit 后,可以在此对 patch 的文件进行修改,删除等。

如果想对文件中的某处进行编辑,点击进入该文件的 review 界面。

点击编辑按钮,进入编辑模式,编辑完 save。

会在 Change 页面看到,点击 Publish Edit 按钮Gerrit 会自动帮你生成一个包含刚刚修改的 patch。

4.2 草稿箱功能

Gerrit 可以作为一个自己的 Change 草稿箱,我们可以将一些还未完成,或者还不想提交 review 的 Change 上传至此处。一来可以作为一个备份,另外在多人互相协助完成同一个功能,或是自己在多台电脑(家里、办公室)上处理未完成的工作。

不同于提交一个正式 Change 的“refs/for/”协议,提交一个 Change 到草稿箱的协议方式为“refs/drafts/”,如下:

$git commit
$git push origin HEAD:refs/drafts/luckyair

草稿箱中的 Change 也可以很方便的转换为正式的 Change而无需重新用“refs/for/”来提交,点击 Publish 按钮转换为正式 Change也可以在此删除此草稿。