Gerrit使用总结

本篇文章接自上一篇文章。

2.Gerrit

Gerrit,一种免费、开放源代码的代码审查软件,使用网页界面,利用网页浏览器,同一个团队的软件工程师,可以相互审阅彼此修改过后的源代码,决定是否能够提交,退回或者继续修改。它使用Git作为底层版本控制系统。作者是Google公司的Shawn Pearce,原先是为了管理Android计划而产生。

这里写图片描述

2.1使用Gerrit开发流程

到用户主目录中看有没有.ssh目录(windows administrator管理员用户C:\Users\Administrator.ssh),如果有,则看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果有,则将id_rsa.pub公钥中的内容全部添加到Gerrit SSH Keys列表中。若是没有.ssh目录,则执行下列命令生成.ssh目录:

ssh-keygen -t rsa -C "youremail@example.com"

然后一路回车,使用默认账户即可。

选择Clone with commit-msg hook,并且选中ssh方式,生成clone链接。

选择ssh方式是因为ssh链接比较安全,而且速度比较快,且每次不用输入git配置的用户名和口令;
Clone with commit-msg hook 是为了在提交commit时修改提交日志记录,在日志记录中添加上Change-id.

默认会在本地建立master分支,本地的master分支与远程的master已经是关联起来的了,即已经存在追踪关系了。

2.1.1 在项目的master分支上提交代码

一般不直接在本地的master分支上直接修改代码,因为若更新代码是没有采用rebase变基会在本地产生一个新的合并节点,但是合并节点是没有Change-id的,push到Review分支时,会提示缺失Change-id,导致提交失败。另外Git鼓励多使用分支,方便代码管理。
Step1. 基于本地master分支建立本地dev分支

git checkout -b dev

修改都在dev分支上进行。

Step2. 更新master分支代并执行rebase变基

git checkout master
git pull
git rebase master dev  // 将master更新后的代码rebase到dev分支
或者 git checkout dev 
git rebase master

上述rebase过程若是出现冲突,就用Git部分提到的冲突解决方法解决。Step2这一步也可以省略,不用更新代码,也可以直接推送dev分支上的提交,不过可能会有冲突,若发生冲突,还得先更新代码,再rebase,所以不妨先更新代码,然后在rebase.
Step3. 将修改推送到远程分支

当前在dev分支,可以直接在dev分支上提交到远程分支
git push origin HEAD:refs/for/master
或者git push origin HEAD:refs/for/master%r=email1@xxx.com.cn,r=email@xxx.com.cn即添加上评审人的邮箱

%r后面一串是评审人的邮箱,这一串命令太长了,若是每次提交都输入一遍着实比较麻烦,这时可以添加一个git命令别名替换上面的命令

git config --global alias.pushmaster 'push origin HEAD:refs/for/master%r=email1@xxx.com.cn,r=email@xxx.com.cn'
--global选项说明该别名命令是全局的,即在别的本地仓库中也可以使用该别名命令。

以后直接执行git pushmaster命令就可以往master分支上提交代码了。

2.1.2在项目的其他分支上提交代码

一般项目中除了master分支都还会有其他分支,例如存在一个V21_bugfix.
Step1. 创建本地V21_bugfix分支

git checkout -b V21_bugfix origin/V21_bugfix

跟master分支上的开发一样,不直接在本地V21_bugfix上开发,因为此V21_bugfix分支与远程V21_bugfix存在追踪关系,让该分支始终与远程V21_bugfix分支同步。基于当前本地V21_bugfix分支建立V21_bugfix_dev分支,后续开发在V21_bugfix_dev上进行。

Step2. 创建基于V21_bugfix的dev分支

git checkout -b V21_bugfix_dev

所有的修改都在V21_bugfix_dev上进行。

Step3. 更新V21_bugfix分支的代码

git checkout V21_bugfix
git pull

Step4.将V21_bugfix分支rebase到V21_bugfix_dev分支

git rebase V21_bugfix V21_bugfix_dev

Step5. 将代码提交到远程V21_bugfix分支

git push origin HEAD:refs/for/V21_bugfix%r=email1@xxx.com.cn,email2@xxx.com.cn

同样可以给V21_bugfix的提交定义一个Git命令别名。

2.1.3 git cherry-pick命令

有时需要将master分支的某个commit合并到另外的分支,这是用cherry-pick命令可以很快的将master分支的改动合并到另外的分支,然后提交到另外的分支上。

Step1.在master分支上找到需要提交的commit-id
Step2.切换到另外一个分支,比如dev分支,执行git cherry-pick <commit-id>
若是没有出现冲突,则直接push即可。若是出现了冲突,解决方法同Git的冲突解决方法。解决完冲突需要重新提交。

注意:若使用cherry-pick摘除某次提交到其他分支时,若该次commit之前还有别的commit提交,则此时会把前面的提交一并摘除到其他分支上,只不过这是cherry-pick的状态显示为冲突,需要手动进行冲突解决,保留需要的代码。

2.2 Gerrit的Change-Id机制与hook机制

Change-Id是Gerrit中的概念,与git是没有关系的,Change-Id只是Gerrit用来追踪具体提交的机制。

2.2.1 Git的hook机制

钩子(hooks)是一些在$GIT-DIR/hooks目录的脚本,在被特定的事件(certain points)触发后被调用。当git init命令被调用后,一些非常有用的示例钩子脚本被拷贝到新仓库的hooks目录中;但是在默认情况下它们是不生效的。把这些钩子文件的”.sample”文件后缀名去掉就可以使它们生效。
hook机制可以理解成回调。各个钩子其实就是一段bash脚本,各钩子脚本的名字都是固定的。当从Gerrit上clone代码时,我们选择Clone with commit-msg hook,在版本库地址中出现以下命令:

scp -p -P 29418 xxx@Gerrit.xx.com.cn:hooks/commit-msg YourProject/.git/hooks/

表示将gerrit的commit-msg脚本下载到本地的YourProject/.git/hooks/目录中。
在gerrit的Change-Id生成机制中,其实就是gerrit利用了commit-msg的钩子,在我们提交代码后,按照一定规则修改了提交日志,在其末尾添加了一行Change-Id.
可以按照下面的命令在本地生成一个Change-Id:

由于本地仓库不是从gerrit下载,所以本地的commit-msg钩子无效,下面的命令需要在从gerrit下clone出来的代码中生效。

$ echo "change-id" > testChangeid.txt
$ ./git/hooks/commit-msg testChangeid.txt
cat testChangeid.txt
2.3 添加Change-Id的方法

方法一:使用git commit –amend选项生成Change-Id
如果缺失Change-Id的是最后一个(head) commit,使用以下命令即可以解决问题:

$ git commit --amend
该命令会打开默认的commit messgae编辑器,一般是vi.
这时什么都不用修改,直接保存退出即可(:wq)。
再次查看git log,就会发现缺失的change-id已经补上了,再次git push即可。
若是想修改change-id,只需要在commit messgae编辑界面上将之前的Change-Id那一行删除掉,然后保存退出即可。

方法二:如果缺失Change-id的不是最后一个commit,可用git reset方法
用reset命令回退到缺失change-id的那个提交,然后重新提交。但是这样做会丢失后面的提交记录。

方法三:使用交互式rebase 找回任意提交位置的Change-Id
这种方法稍微麻烦一些。具体可以参考交互式修改Change-Id.

Git学习网站:廖雪峰Git学习
Gerrit学习链接:Gerrit代码Review入门实战

阅读更多
文章标签: Gerrit
个人分类: Git&Gerrit
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭