Gerrit,一种免费、开放源代码的代码审查软件,使用网页界面。利用网页浏览器,同一个团队的软件程序员,可以相互审阅彼此修改后的程序代码,决定是否能够提交,退回或者继续修改。
本文主要记录一个gerrit的用户如何拉取代码,并做修改提交,等待审核的一个过程。
如果你是一个刚接触gerrit的用户使用者,可以继续往下阅读。如果你已经是一名old bird可以忽略~~~
注册Gerrit账户,需给联系Gerrit管理者获取账号。
假如你已经有了账号,请登录你的gerrit服务。
一旦你登录了账号,并且没有设置过邮箱,那么请注册:
用户注册邮箱请参考这里
如果你是一个新用户,请将你工作的本机秘钥添加到你的gerrit账号下,以便可以正确拉取推送项目。
# 查看当前用户是否存在秘钥, 如果不存在需要通过ssh-keygen进行生成
# 秘钥生成
ssh-keygen -t rsa -C "[email protected]"
# 复制秘钥
cat ~/.ssh/id_rsa.pub
如果提示权限问题:可能是版本级别太高,通过以下方式生产秘钥
ssh-key -t ed25519 -C "[email protected]"
# 打开CMD DOS生成秘钥
ssh-keygen -t rsa -C "[email protected]"
当获取到了公钥之后,登录到gerrit服务,将公钥添加到gerrit账户中:
复制公钥:
用户开发者一旦获取到自己的gerrit账号后,就已经有了自己相应的权限了。
开发者可以通过BROWES->Respositories中查看自己账号下挂载了的项目情况。
我们可以看到下图显示了只有一个tinyalsa的项目
那么我们如何拉取项目呢。 只有点击tinyalsa进入界面就可以看到有两种拉取方式:
with commit-msg hook
commit-msg 是一个脚本文件,该脚本对于 Gerrit 的使用非常重要,使用 Gerrit 必须要有此脚本,否则在本地的修改版本无法提交至 Gerrit 中,会报错:missing change-id in commmit message footer,表示该版本提交没有 change-id。
所以我们必须使用这一种方式,不然无法得到审核。
without commit-msg hook
这一种也是我们常用的git克隆方式,应该很熟悉。 如果项目被设置了权限,该方法是无法进行修改提交的,必须拉取commit-msg hook脚本才行
到这里,开始克隆代码
# 我们先创建一个测试目录
mkdir -p ~/mtk/test_gerrit/own/user2
# 开始clone
git clone "ssh://[email protected]:29418/tinyalsa" && scp -p -P 29418 [email protected]:hooks/commit-msg "tinyalsa/.git/hooks/"
cd tinyalsa
release@release:~/mtk/test_gerrit/own/user2/tinyalsa$ ls
Android.bp MODULE_LICENSE_BSD NOTICE README include mixer.c pcm.c tinycap.c tinyhostless.c tinymix.c tinypcminfo.c tinyplay.c
release@release:~/mtk/test_gerrit/own/user2/tinyalsa$
我们那到了代码之后, 修改和提交完全和git的操作一样。
如下,我们对README进行修改并提交:
# 修改README,增加test code review by user2 modfiy
release@release:~/mtk/test_gerrit/own/user2/tinyalsa$ vi README
release@release:~/mtk/test_gerrit/own/user2/tinyalsa$ git add README
# 提交到版本库
release@release:~/mtk/test_gerrit/own/user2/tinyalsa$ git commit -m "test code view user2"
[master 19d61bc] test code view user2
1 file changed, 1 insertion(+)
# 推送到远程仓
release@release:~/mtk/test_gerrit/own/user2/tinyalsa$ git push origin HEAD:refs/for/master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 48 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 359 bytes | 359.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2)
remote: Processing changes: refs: 1, new: 1, done
remote:
remote: SUCCESS
remote:
remote: http://10.66.xxx.xx:8081/c/tinyalsa/+/41 test code view user2 [NEW]
remote:
To ssh://localhost:29418/tinyalsa
* [new reference] HEAD -> refs/for/master
release@release:~/mtk/test_gerrit/own/user2/tinyalsa$
以上开发者有没有注意到最后推送到远程仓用的是
# 用的是
git push origin HEAD:refs/for/master
# 而不是我们常用的
git push origin master or git push
那是因为我们clone with commit-msg hook,推送代码必须得到审核,不经过审核的代码是没有权限直接推送到远程仓的。
HEAD:refs/for/master - 就是将本地HEAD推送到refs/for/master这个临时仓中待审核, 审核通过后自动推送到远程仓中并同步到gitlab远程服务器中。
release@release:~/mtk/test_gerrit/own/user2/abandoned/tinyalsa$ git push origin HEAD:refs/for/master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 48 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 311 bytes | 311.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2)
remote: Processing changes: refs: 1, done
remote: ERROR: commit c8d5423: missing Change-Id in message footer
remote:
remote: Hint: to automatically insert a Change-Id, install the hook:
remote: gitdir=$(git rev-parse --git-dir); scp -p -P 29418 [email protected]:hooks/commit-msg ${gitdir}/hooks/
remote: and then amend the commit:
remote: git commit --amend --no-edit
remote: Finally, push your changes again
remote:
To ssh://10.66.xxx.xx:29418/tinyalsa
! [remote rejected] HEAD -> refs/for/master (commit c8d5423: missing Change-Id in message footer)
error: failed to push some refs to 'ssh://10.66.xxx.xx:29418/tinyalsa'
当代码正确提交到分支 refs/for/* 后,需要登录Gerrit界面为刚才的提交添加相应的审核者。
1.这时我们登录到gerrit账户后,通过YOUR->Changer就可以看到刚才的提交记录:
2.查看状态,发现有一条需要被审核:
3. 点击进去设置审核者
如此,我们增加了一个gerrit的账号进行审核。
这样我就等待审核就可以了,如果项目提交顺利通过该过程就结束了。
如果审核被打回,那我们就需要重新修改在提交。
当一个提交被审核者审批之后,会有相应的邮件通知,或者通过gerrit WebUI进行查看状态。
主要有以下几个状态:
一旦开发者提交了审核,相应的审核人员将会接收到邮件提示通知,或者通过YOUR->Changes->Incomming reviews查看有待审核记录并做相应的审批。
以上知道了有哪些待审核的提交之后,我们就可以针对这些提交做批示。
在Incomming reviews中选择一个待提交的申请,点击进入:
我们选择test code view user2这个提交:
审核者认为可以通过审核,可以点击右上角 CODE-REVIEW+2确认通过审核了。同时左上角的状态也将跟着变成Active->Ready to submit. 同时状态的改变都会有邮件通知。
最后由审核者确认SUBMIT同意合并,一旦合并将会同步到gitlab远程服务器中。
登录gitlab进行确认一下,确实已经被提交了:
当开发者的一个提交被审核者打回了,怎么办?
主要分两种情况:
只提交了一个commitA,被审核者驳回,本地没有其他提交
已经提交了一个commitA, 之后又提交了commitB, 但是commitA被审核者打回
大多情况下一个项目都是有多人维护开发,有时自己刚修改好了某一功能,在提交后,在gerrit中状态中显示Merger conflict, 这是因为在你提交之前已经有其他人优先于你的提交。
release@release:~/mtk/test_gerrit/own/user2/abandoned/tinyalsa$ git push origin master
To ssh://10.66.xxx.xx:29418/tinyalsa
! [rejected] master -> master (fetch first)
error: failed to push some refs to 'ssh://10.66.xxx.xx:29418/tinyalsa'
这是因为你在拉取gerrit的代码是没有权限直接推送远端服务器,必须要经过审核才行。
正确的做法应该是:
git push origin HEAD:refs/for/master # master是要推送的分支名, 如developer
# 修改文件
release@release:~/mtk/test_gerrit/own/user2/abandoned/tinyalsa$ vi README
release@release:~/mtk/test_gerrit/own/user2/abandoned/tinyalsa$ git add README
# 提交文件到本地仓
release@release:~/mtk/test_gerrit/own/user2/abandoned/tinyalsa$ git commit -m "test without ci-msg"
[master c8d5423] test without ci-msg
1 file changed, 1 insertion(+)
# 推送到远端gerrit仓
release@release:~/mtk/test_gerrit/own/user2/abandoned/tinyalsa$ git push origin HEAD:refs/for/master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 48 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 311 bytes | 311.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2)
remote: Processing changes: refs: 1, done
remote: ERROR: commit c8d5423: missing Change-Id in message footer
remote:
remote: Hint: to automatically insert a Change-Id, install the hook:
remote: gitdir=$(git rev-parse --git-dir); scp -p -P 29418 [email protected]:hooks/commit-msg ${gitdir}/hooks/
remote: and then amend the commit:
remote: git commit --amend --no-edit
remote: Finally, push your changes again
remote:
To ssh://10.66.xxx.xx:29418/tinyalsa
! [remote rejected] HEAD -> refs/for/master (commit c8d5423: missing Change-Id in message footer)
error: failed to push some refs to 'ssh://10.66.xxx.xx:29418/tinyalsa'
release@release:~/mtk/test_gerrit/own/user2/abandoned/tinyalsa$
这时因为你在拉取gerrit仓时没有同步hook/commit-msg脚本文件, 这个文件对需要审核的gerrit必须要有。
解决:
方法一: 在拉取代码时直接通过gerrit WebUi提供的download连接克隆工程
方法二: 已经拉取了代码并也做了修改,此时不想在重新拉取工程。那么可以在原有的工程下只拉取commit-msg
# 进入工程目录 tinyalsa,执行以下命令
gitdir=$(git rev-parse --git-dir); scp -p -P 29418 [email protected]:hooks/commit-msg ${gitdir}/hooks/
当你在做push的时候提示邮箱地址不匹配:
remote: ERROR: commit bebf9e6: email address [email protected] is not registered in your account, and you lack ‘forge committer’ permission.
这是因为你gerrit账号没有注册邮箱,或者已经注册了但是本地git 配置中的user.email和注册的邮箱不一致所致。
解决方法:
# 1, 首先注册gerrit邮箱, 请参考邮箱注册小节
# 2, 修改本地git user.email 配置
git config user.email [email protected]