Gerrit的基本使⽤
1、Gerrit的基本介绍
Gerrit 是⼀个Git服务器,它基于 git 版本控制系统,使⽤⽹页界⾯来进⾏审阅⼯作。Gerrit 旨在提供⼀个轻量级框架,⽤于在代码⼊库之前对每个提交进⾏审阅,更改将上载到 Gerrit,但实际上并不成为项⽬的⼀部分,直到它们被审阅和接受。代码审查是Gerrit的核⼼功能,但仍是可选的,团队可以决定不进⾏代码审查⽽⼯作。
Gerrit 是⼀个临时区域, 在提交的代码成为代码库的⼀部分之前, 可以对其修改进⾏检查。代码修改的作者将提交作为对 Gerrit 的更改。在Gerrit中,每个更改都存储在暂存区域中,可以在其中进⾏检查和查看。仅当它被批准并提交时,它才被应⽤到代码库中。
其实,Gerrit 就相当于是在开发员将本地修改提交到代码仓库之前的⼀个审核⼯具。在这个审核⼯具中,你可以查看该提交者在本次的的提交中的修改,然后再决定是否可以将该修改提交给仓库。
2、Gerrit的页⾯介绍
2.1、CHANGES菜单
点击 changes 可以查看所在项⽬的所有审批记录,共有三种状态:open、merged、abandoned。
open:还未审核、审核不通过、审核通过还未提交到远程仓库的提交
merged:审核已通过并已提交到远程仓库的提交
abandoned:已取消审核的提交
2.2、YOUR -> CHANGES 菜单
点击 your -> changes 可以查看当前登录⽤户的名下的所有审核记录,包括本⼈提交和本⼈需审核的。
outgoing reviews:本⼈待被审核的提交
incoming reviews:别⼈提交,本⼈需要审核的提交
recently closed:已关闭的提交,包括已经推送到远程仓库和已经取消审核的
2.3、Repositories
点击 repositories 可以看到⾃⼰有权限看到的所有项⽬。
点击进⼊某个项⽬,可以查看该项⽬的下载链接,共有三种下载⽅式:
anonymous http:链接⾥⾯⽆⽤户名,下载时需输⼊⽤户名和密码
http:链接⾥待⽤户名,下载时⽆需输⼊⽤户名,但需要输⼊密码
ssh:免密⽅式,⽆需输⼊⽤户名和密码,但需将本地⽣成的公钥保存在 Gerrit ⽹页中
3、在Gerrit上的代码克隆⽅式
在Gerrit上有三种克隆⽅式,如上⾯的 2.3 所⽰,跟在 github 上克隆代码没什么区别。
在 Gerrit 中,你可以选择 clone with commit-msg hook 选项来进⾏克隆,该选项在上⾯的三种克隆⽅式中都有,该⽅式会将 Gerrit 上的 commit-msg 脚本拷贝在你的本地仓库中,由此你就可以将代码提交到 Gerrit 中(未验证)。 commit-msg 脚本是使⽤ Gerrit 的⼀个⾮常重要的步骤,不可或缺,后⾯会介绍。
4、Gerrit 上的钩⼦ commit-msg
commit-msg 是⼀个脚本⽂件,该脚本对于 Gerrit 的使⽤⾮常重要,使⽤ Gerrit 必须要有此脚本,否则在本地的修改版本⽆法提交⾄ Gerrit 中,会报错:missing change-id in commmit message footer,表⽰该版本提交没有 change-id。
commit-msg 脚本⽂件应该放在代码根⽬录的 .git/hooks ⽂件夹下,该⽂件夹下有许多的脚本⽂件,这些脚本⽂件也被称之为钩⼦,在被特定的事件触发后这些⽂件将会被调⽤。当⼀个 git 仓库被初始化⽣成时,⼀些⾮常有⽤的钩⼦脚本将会⽣成在仓库的 .git/hooks ⽬录中,但是在默认情况下它们是不⽣效的,把这些钩⼦⽂件的 ”.sample”⽂件后缀名去掉就可以使它们⽣效。
Git 提供了4个提交⼯作流钩⼦:pre-commit、prepare-commit-msg、commit-msg、post-commit。其中 commit-msg 钩⼦,会在我们执⾏ git commit 时被执⾏。
在 gerrit 的 Change-Id ⽣成机制中,gerrit 会利⽤ commit-msg 的钩⼦,在我们提交代码后,按照⼀定规则修改提交⽇志,在其末尾添加了⼀⾏
Change-Id。
4.1、如何给本地仓库添加钩⼦ commit-msg
4.1.1、在克隆仓库时选择带 commit-msg 的⽅式进⾏克隆
在 Gerrit 中克隆仓库有三种⽅式,anonymous http、http、ssh,这三种⽅式当中都有⼀个 clone with commit-msg hook 选项可供选择,选择该选项的链接来克隆项⽬,将会⾃动在你本地的仓库中⽣成 commit-msg 钩⼦,这样在你今后的本地提交当中 commit-msg 都会起作⽤,将会给每个提交⾃动⽣
成⼀个 chang-id,保证了你的本地提交可以推送到 Gerrit 中。
4.1.2、在本地仓库直接使⽤ git 命令来拷贝Gerrit的commit-msg
如果在克隆时选择的不是 clone with commit-msg hook 链接,那么本地的仓库当中的 commit-msg 将不会起作⽤,你的本地提交不会⽣成 change-id,也就⽆法将提交推送⾄ Gerrit 中。
此时你可以在本地仓库中的根⽬录下使⽤下⾯的 git 命令来拷贝 Gerrit 的 commit-msg:
scp -p -P 29418 yourName@Gerrit服务器地址:hooks/commit-msg  "hooks⽂件夹路径"
//实例:
scp -p -P 29418 wenxuehai@21.96.221.111:hooks/commit-msg  ".git/hooks"
上⾯命令表⽰将 gerrit 的 commit-msg 脚本下载到本地仓库的 t/.git/hooks/ ⽬录中。执⾏上⾯的命令,你的本地仓库的 .git/hooks ⽂件夹下的 commit-msg ⽂件将会被 Gerrit 的 commit-msg ⽂件覆盖掉,由此你今后的提交当中也会⾃动⽣成⼀个 change-id。
5、Gerrit 中的 change-id
待完善。
6、如何将本地提交推送⾄Gerrit中
在 Gerrit 上⼯作和在 github 上⼯作的差别不⼤,两者都是基于 git 版本控制系统的。当我们在本地⼯作时,除了需要有⼀个 commit-msg 钩⼦⽂件外,其他的并没有区别。
当我们在本地进⾏了修改,并且进⾏了 commit ⽣成了版本后,就可以将本地提交推送⾄ Gerrit 中,不过推送命令和平常的不太⼀样:
git push origin HEAD:refs/for/远程分⽀名
//实例:
git push origin HEAD:refs/for/2020_branch
提交更改是什么⼀旦你在本地完成commit,就需要把他 push 到Gerrit,这样才能被审核者 review,这就需要git push到Gerrit server。
可以看到 HEAD 被推送到 refs/for/2020_branch,这是 2020_branch 的的魔幻分⽀,⽤于创建 review。对于每⼀个分⽀,Gerrit都会追踪⼀个魔幻分⽀refs/for/branchName。
7、提交报错
7.1、提⽰:commit xxx:missing change-id in commmit message footer
在将本地修改推送到 Gerrit 上时(请注意往Gerrit上推送必须使⽤git push origin HEAD:refs/for/branchName命令),有可能会报以上的错误,表⽰没有 change-id,提⽰信息还标出了是哪次提交缺少 change-id。
注意:在将修改推送到 Gerrit 上时,本地每次提交的修改都必须有 change-id,可以使⽤ git log 命令来查看哪次提交是没有 change-id 的,但凡有⼀个提交没有chang-id,本地代码都⽆法推送⾄ Gerrit 上。
⾯对这种情况有以下解决⽅法:
请注意,下⾯的解决⽅法的前提是本地的commit-msg脚本⽂件已经替换成了Gerrit上的,使⽤ Gerrit 必须先拷贝commit-msg脚本⽂件,如果还没有的话请参考4.1.2 先拷贝脚本⽂件,否则下⾯的解决⽅法仍然⽆法解决问题
7.1.1、标出的缺少 chang-id 的提交就是最近的⼀次提交
此时⼀般来说,git 就会提⽰你需要进⾏的操作:gitdir=$(git rev-parse .... ${gitdir}/hooks/ ,然后需要: git commit --amend --no-edit,我们只需将 git 提⽰的命令复制下来操作即可:
//先执⾏下⾯命令,其实下⾯的命令就是拷贝Gerrit中的commit-msg脚本⽂件,如果你已经拷贝了的话可以不⽤执⾏下⾯的命令也⾏
gitdir=$(git rev-parse --git-dir); scp -p -P 29418 yourName@gerrit服务器地址:hooks/commit-msg ${gitdir}/hooks/
//实例:
gitdir=$(git rev-parse --git-dir); scp -p -P 29418 wenxuehai@gerrit21.96.221.111:hooks/commit-msg ${gitdir}/hooks/
//再执⾏
git commit --amend --no-edit
7.1.2、缺少 change-id 的提交并不是最近的⼀次提交
如果缺少 change-id 的提交并不是最近的⼀次提交的话,上⾯的解决⽅法就⽆法解决问题,因为将修改推送⾄ Gerrit,必须要求每次提交都有 change-id。
此时我们可以使⽤ git log 命令来查看是哪次提交没有 change-id,或者 git 提⽰信息也会标出是哪次提交没有 change-id,然后记下该次提交的下⾯那个提交的 commit id,即前⼀次提交的 commit id。
⽐如下图:
假设上图中,提交2缺少了 change-id,那么我们就需要记下提交1的commit id:8ca4e3c3d9133f33fa36f063bfc2767b56c5cd3a。
然后执⾏下⾯的命令:
git reset --soft 8ca4e3c3d9133f33fa36f063bfc2767b56c5cd3a
//执⾏完上⾯的命令后咱们可以查看状态,此时可以看到本地的修改并没有丢失
git status
//然后再照常提交⼀个版本
git add .
//此时提交过后就可以看到本次提交的版本就会有 change-id 了
git commit -m '提交修改'
//然后推送即可
git push origin HEAD:refs/for/branchName
可参考:
如果缺少 change-id 的不⽌⼀个提交,这时就需要从最近的⼀个缺少 change-id 的提交照着上⾯的操作进⾏修改,或者直接从最晚的那个缺少change-id 的提交进⾏操作?(未尝试过)
8、提交成功但在Gerrit上查看显⽰在merge conflict状态
8.1、出现merge conflict的原因
由于有 code review 的存在,有可能出现这种情况:同时有多个⼈的代码被 review,如果有⼀个⼈改了与你相同地⽅的代码,并且他的代码先通过review 并被合进了远程代码库。当你的代码通过 review 并进⾏合并,此时会产⽣冲突,你的提交也就会显⽰为 merge conflict 状态。在 Gerrit ⽹页上的 CHANGES -> open 上就可以看到该冲突提交,该提交⽆法 submit 到远程仓库上。如果你不解决掉该冲突提交的话,你在本地的之后的提交也⽆法合并到远程仓库上,因为你本地的提交都是基于前⾯的那次有冲突的提交的。
8.2、解决⽅法
1)先在 Gerrit 的 CHANGES -> open 上到该提交,然后点击 ‘ABANDON' 按钮将该提交取消掉。
2)在本地到该提交的上⼀个提交版本的 commit id,注意,是⽐这个出现冲突的版本更早提交的版本,⼀般来说,这个版本已经提交到了Gerrit上的
3)使⽤ git reset 的混合模式(git reset --mixed commitId)或者是软模式(git reset --soft commitId)回退⾄上⾯记录的 commit id 的版本,使⽤这两种模式不会丢失你本地的修改,所以⼤可以放⼼。
4)使⽤ git stash 命令将本地修改储存起来,然后再拉取最新代码,拉取完毕后应⽤储存 git stash pop,如果有冲突就解决冲突即可。然后就可以将版本提交⾄Gerrit上了。
综上所述,其实出现这种状态主要就是因为你的代码和别⼈的代码产⽣了冲突,并且别⼈的代码先⼀步通过了 review ⽽且合并到了仓库当中,⽽你的代码通过 review 但是⽆法合并到仓库中,因为两⼈的修改产⽣了冲突,此时就要解决冲突。
你只需回退⼀下版本,然后拉取远程代码,在本地解决冲突,然后就可以将本地版本提交⾄ Gerrit 上了。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。