干货 | 携程Hybrid代码评审服务

2019-04-22 10:45:01 浏览数 (1)

作者简介

苏玲,5年软件配置管理及7年持续集成经历。曾在苏州科达科技和大众点评任资深配置管理工程师,目前为携程代码中心负责人,专注于代码相关的平台建设,致力于提高研发效率与研发质量。

李海涛,目前为携程代码中心高级研发工程师,负责实现了Gitlab sharding和hybrid的代码评审服务。

一、综述

携程从2013年开始引入了Gerrit和Gitlab两款代码评审服务,开发团队可自行选择其一用来管理代码。

其中,Gitlab开源项目经过四年的发展,持续优化了代码管理相关功能,还提供了很多DevOps的增值服务。而Gerrit提供的pre-commit的方式,也有其优势。

为了代码平台统一,携程代码中心团队在Gitlab上提供了类Gerrit的代码评审方式,推出了既有change@Gerrit方式又有merge request@Gitlab方式的hybrid的代码评审服务。

本文先分析两种review方式的优点,然后通过介绍几个场景来指出Gitlab中增加change功能的必要性,以及如何把hybrid的服务用到极致,并归纳出几类代码评审模式分别适合的场景,希望对开发团队有所帮助。

二、简称

本地开发每个commit都自动产生一个change,没经过review的变更不能进入公共的Git仓库,这种方式我们简称为CHANGE 。

每次review都要提交两个分支进行合并的Merge Request,这种方式简称为MR 。

三、Gerrit与Gitlab的PK

我们只比较两个平台在代码评审上的差异,然后提炼出优点。

Gerrit提供了pre-commit的评审方式,通俗地说,就是没经过review的变更是不会进入到Git仓库里面。而Gitlab没有pre-commit的功能,只提供了post-commit的功能,也就是在同一个Git仓库中,任何开发人员必须向Git仓库推送自己的分支,然后发起Merge Request后才能请别人帮忙review代码。

Mr. Gitlab :你不想正式的仓库被坏代码弄脏,那你用Gitlab fork的方式好了,只要不接受Merge Request,脏的代码只会存在fork出来的仓库里面,正式的仓库一样可以实现pre-commit的功能。

Mr. Gitlab:我们团队采用的是特性分支开发的分支模型,需求管理系统中新增一个需求就会自动创建一个分支,每个分支名就能看出特定的一个功能点,这个多好,想知道一个迭代周期有多少个功能要交付,看看有多少分支就行了,而且这些新建的分支就像计划任务一样提醒着开发人员。代码评审就用Merge Request,当特性分支开发完毕,发个Merge Requst到master分支就行。

Mr. Gerrit:Gerrit也可以为每个特性分支创建分支的,还能为特性分支上的每个commit建立review申请。另外,你们每次做review,都得打开Gitlab的页面,手工发起一个Merge Request,这个太麻烦了,大家看看Gerrit的做法吧,开发人员只要在自己的开发设备中,push一个特殊的变更,Gerrit上就能自动创建一个change了,根本不用人再登到Gerrit系统上去申请review。

Mr. Gitlab:我不喜欢Gerrit对每个commit 单独地做review,用MR多好,一个分支合入另一个分支做个review,这样虽然一次性review多一点,但不用在多个changes中跳来跳去,而且分支是可以多人共享的,我一次性可以review多个人的变更。

Mr. Gerrit:我觉得对单个commit做review挺好的,一个功能一个commit,这样更容易发现问题。

Mr. Gerrit:CHANGE的方式,很容易创建出linear history的分支,这样便于用bisect定位问题的出处。MR行不行呢?

Mr. Gitlab:MR当然也可以,虽然是两个分支之间发起merge request,但是项目策略配置为Fast-forward merge就行啦。 ”

看了上面的讨论,我们发现有些所谓的“优点“并不明显,需要在特定场景下才拥有,有些优点则很明显。我们用表格形式做个归纳:

具体优点

是/否优点

Gerrit具备

Gitlab具备

PK结论

未经review的代码不会进到Git仓库

是(但要fork仓库,管理成本增加)

Gerrit 胜出

Push的时候自动发起了review的申请

Gerrit 胜出

Review一个分支,而不用review每个commit

是@某些情况

Gitlab 胜出

Review单个commit,保证review的质量

是@某些情况

Gerrit 胜出

能实现linear history

打平

上面PK的内容没有涉及review功能的所有特性,也不是用来说明Gitlab的review不如Gerrit的,而是告诉大家,某些情况下团队确实需要Gerrit的这种pre-commit的方式。我们不妨继续探讨一下,哪些情况下适合用CHANGE 。

四、特别适合用CHANGE的场景

场景1:主干分支开发的项目。

因为所有的变更都要求在第一时间提交到唯一的开发分支上,保持持续的集成,如此一来,特性分支就没必要存在了。这种情况下,用CHANGE最适合。

开发在本地始终基于主干分支做开发,开发完毕,直接向远端的refs/for/主干分支push即可。一提交,远端自动创建一个change,该change通过review后,其对应的commit就合入到主干分支;如果review没被通过,则变更的内容就不会进入到主干分支。

场景2:特别重视代码质量的团队。

此类团队不允许质量低劣的commit存在仓库中,也不想用fork的方式,因为fork的方式不够简洁和直接,fork出去的仓库需要经常fetch原仓库,需要维护多个remote 。

场景3:有较多开发新手的团队。

新手提交的变更先经过review然后才能进入到Git仓库。

五、CHANGE和MR同时使用的场景

给Gitlab引入CHANGE,很自然地会想起一些问题“难道仅仅是为了让Gerrit顺利下线,我们才把CHANGE引入到gitlab吗?”或者“现有采用Gitlab MR的团队是否也能享受CHANGE带来的好处呢?”

静下来想一想,还真的存在下面的场景,如果同时使用CHANGE和MR,可以有效提高代码评审的效果。

团队特征:

  • 采用特性分支开发模式,每个功能对应一个分支。
  • 特性分支开发完毕,合入master分支后发布。
  • 有不少开发的新手。

开发流程:

  • 甲、乙、丙三人同时负责A功能的研发,共同分享feature-A分支。
  • 甲负责review乙、丙的代码。
  • Feature-A分支设为保护分支,变更前需review代码。
  • 乙和丙在本地基于Feature-A开发,自测完成后push到refs/for/Feature-A。
  • 甲在gitlab上review后,乙、丙的变更被合入到Feature-A 。
  • 然后甲向master发起了一个Merge Request。
  • 由上一级集成人员review后,最终Feature-A被合入到了master 。

“CHANGE和MR同时使用”,比起 “只使用MR”,优点很明显:

以前只有MR的情况下,如果甲要review乙和丙的代码,除了结对编程外,还有一种方式,把Feature-A保护起来,不允许直接push,然后,甲和乙基于Feature-A创建新的分支,开发完成后再Feature-A向发起MR 。而“CHANGE和MR同时使用”,可以省掉额外新建分支的麻烦,且省掉了发起MR的麻烦。

我们不妨用下面的简图呈现CHANGE和MR的关系:

如此一来,在不增加远端仓库分支的情况下,基层review人员依赖CHANGE,保证每个commit的代码质量,从而确保特性分支的质量;另一方面,主干分支的集成人员借助MR,无需在个人环境上做分支的集成,待review人员完成评审后,他们就能一次性地在Gitlab界面上把特性分支合入到主干分支,从而保证master主干分支能被高效地集成。

六、Hybrid代码评审服务的模样

1)尽可能保留Gerrit本地操作的方式:

git push origin HEAD:refs/for/目标分支 。

2)项目首页,提供CHANGE的clone方式:

3)CHANGE和MR并存:

七、代码评审模式的类型与适用场景

MR和CHANGE都提供代码评审的功能,并且携程Gitlab平台同时支持这两种功能。非常自然地,大家极有可能会问:“什么时候该用MR,什么时候用CHANGE,什么时候同时使用,什么时候可以都不用呢?”

我们用下表做个归纳:

序号

模式

适合的场景

1

CHANGE

同时满足以下几个条件:产品有质量要求。主干开发主干发布。

2

CHANGE MR

同时满足以下几个条件:产品有质量要求。非“主干开发主干发布”。不少能力较弱的开发人员。

3

MR

同时满足以下几个条件:产品有质量要求。非“主干开发主干发布”。很少能力较弱的开发人员。

4

无代码评审

对质量没什么要求的项目。或者每个成员都是神一样的人,永远交付高质量的代码。

  • 产品有质量要求。
  • 主干开发主干发布。

2CHANGE MR同时满足以下几个条件:

  • 产品有质量要求。
  • 非“主干开发主干发布”。
  • 不少能力较弱的开发人员。

3MR同时满足以下几个条件:

  • 产品有质量要求。
  • 非“主干开发主干发布”。
  • 很少能力较弱的开发人员。

4无代码评审

  • 对质量没什么要求的项目。或者
  • 每个成员都是神一样的人,永远交付高质量的代码。

结合上面的分析与归纳,大家不难发现:这套既有CHANGE又有MR的hybrid的代码评审服务,为那些分支策略多样性的公司的代码评审提供了灵活性和高效性。

作为一款代码评审服务,它不仅仅适合携程,同样也适合与携程有类似特征的公司。

八、结束语

hybrid代码评审服务的推出,预示着携程即将全面下线Gerrit,统一代码平台为Gitlab,期待携程的研发能从中获益,从而进一步提高review效率。

我们也希望hybrid的方式,能给代码平台的建设提供一种新的思路。当崭新的事物出现的时候,我们不妨听听用户的心声,看看如何能把旧事物里面好的一些设计理念有机地结合到新事物中。如果hybrid得非常巧妙的话,很可能会有非常棒的效果。

0 人点赞