大道至简,知易行难
广阔天地,大有作为

SVN2GIT之路(四)基于Bitbucket的分支管理及代码评审实践

系列文章:

SVN2GIT之路(一)引言

SVN2GIT之路(二)SVN到Git的手工迁移(保留所有分支、Tag及提交记录)

SVN2GIT之路(三)SVN与GIT的双向自动镜像

Git的分支模型有很多种,例如最经典的Git分支模型如下:

C:\Users\mlkui\AppData\Roaming\Foxmail7\Temp-14212-20200606120550\Attach\InsertPic_9B25(06-08-13-13-43).jpg

鉴于:

  • 具体组织、具体组织下产品线、产品线下实际项目组、项目组下的实际开发单元具体治理情况的意识形态不同;
  • 各交付单元所配套的开发人员素质、技术管理能力、测试机制、上线机制(投产窗口、投产方式)、运维方式等的不同;

在具体开发中可能采用的分支模型及分支管理方式也不尽相同,具体如何管理分支也是仁者见仁智者见智的问题。结合数个项目组、数十个项目的实际工程经验,在偏向于严格测试及投产的开发环境下,经过讨论后,推荐使用如下的分支模型(针对一个具体的Repository而言,一个Repository对应一个具体的工程):

  • 发版分支,形如:release/xxx-dev、release/xxx-sit、release/xxx-uat、release/xxx-ver,指部署在开发、SIT、UAT、VER环境的分支,直接通过Jenkins进行持续集成。master分支直接对应生产分支;
  • 缺陷修复分支,形如:bugfix/JIRA-123-mei-fix_some_functions,缺陷修复分支往往需要同时合并至DEV、UAT,并在合适的时机合并至VER或master中,因此可以考虑引入自动合并。但是,在实践中由于需要选择上线时机,往往将其合并至某个功能分支或延迟至投产前再合并也可以。注意,在投产受控严格的环境下区分hotfix分支意义不大,且bugfix的语义往往已经很弱,除紧急变更外的缺陷修复往往很可能是合并到下面的项目分支中进行的,这里之所以将bugfix单独抽出是为了方便自动化合并;
  • 项目分支,形如:project/EXAMPLE-5i5j0901、project/EXAMPLE-sub0928、project/EXAMPLE-limit0821,一般指某个大的功能点(通常的分支模型中可能将其成为feature分支,即所谓的功能分支。但在投产严格受控的环境中,过长的投产周期往往导致一个功能分支中巨大、包含非常多的Jira任务,因此再使用feature分支的称呼或者做法并不恰当),这些大功能点的开发往往需要跨越几个发布周期才能开发完成,通常由若干具体的Jira任务组成,大多是一个持续迭代项目中不断迭代的大功能点,作为整体提交至UAT/VER/master,或提交至其他项目分支。需要注意,这里的“项目”更多指的是功能维度,而非实际存在的真实项目。需要注意,项目分支是用来处理“临时无法投产”等情况的重要抓手,多数是根据测试情况、将项目分支作为整体PR/Merge到SIT–>UAT–>VER–>master的;
  • 任务分支,形如:task/EXAMPLE_5i5j0901_nielinju_EX-100_kaihu、task/EXAMPLE_5i5j0901_fuqi_EX-106_qianyue,指关联到某个具体Jira任务的分支,在Jira中直接创建并同步至Bitbucket。注意,任务分支的命名需要易读,不应仅仅以Jira任务编号命名,至少需要体现出对应的Jira任务编号、开发人员、大致功能。这是因为,在投产严格受控的环境中投产周期间隔往往过长,大规模多人并行开发时往往导致在多个投产间隔之间、不同的测试阶段下存在产生大量任务分支,如果分支的名称可读性查那么管理时将非常困难;

请注意,如果需要使用SVN Mirror实现SVN与Git之间的双向同步,那么若为SVN标准代码仓库(branches、tags),则可以用前缀路径区分;若非SVN标准代码仓库,对于当前的Bitbucket而言,即使使用SVN Mirror进行了映射且可以正常import,如果分支名称带有前缀那么也无法从Git同步到SVN,怀疑是Bitbucket低版本的BUG,因此建议不使用前缀是而使用扁平的结构。不过,在绝大部分情况下我们无需使用SVN Mirror,为了后续自动化时根据分支名称表达式匹配,推荐使用前缀方式的分支名称。

一、总体的分支合并逻辑

H:\微信截图_20200928145024.png

  1. 大功能点准备开发时,一般从master分支创建项目分支(除非是要拆分某个项目,则基于该特定的项目分支创建);
  2. 开发人员所有提交的代码必须关联到Jira任务,该项目分支的功能点被拆分为若干个Jira任务,如JIRA-123到JIRA-234。开发人员在进行某个任务的开发时,在Jira中直接创建或复用任务分支(因此一个任务分支往往关联至一个或多个Jira任务);
  3. 开发人员完成一个Jira任务的开发时,提交PR,将该Jira任务对应的任务分支合并至项目分支;此PR若要合并,需要满足项目组的具体评审要求(交叉评审、分级评审等),并会经过多轮的Need Works后被最终Approve,并Merge到项目分支中;

H:\微信图片编辑_20200424175134.jpg

  1. 当项目分支开发基本完成时,将项目分支通过PR或手工Merge方式合并入DEV分支(若是通过PR进行则可以进行代码评审),供DEV测试;
  2. DEV测试中发现问题时,依然通过PR提交至项目分支,并经由项目分支合并至DEV分支;
  3. 当进入UAT阶段时,将项目分支通过PR或手工Merge方式合并入UAT分支(若是通过PR进行则可以进行代码评审),供UAT测试;
  4. UAT测试中发现问题时,依然通过PR提交至项目分支,并经由项目分支合并至UAT分支;
  5. 此时的缺陷修复涉及是否合入DEV分支的问题。若缺陷修复时使用了bugfix标识,则可以考虑通过自动化手段自动合入对应分支;若没有使用bugfix标识,则可以按需手工合入DEV分支;
  6. 当进入VER阶段时,将项目分支通过PR或手工Merge方式合并入VER分支(若是通过PR进行则可以进行代码评审),供VER测试;
  7. VER测试中发现问题时,合并方式同上;
  8. 当准备生产发布时,将项目分支通过PR或手工Merge方式合并入master分支(若是通过PR进行则可以进行代码评审,一般由于版本环境已经妥善验证因此此时只是简单确认);

二、冲突处理逻辑

对于冲突:

  1. 冲突是正常的,不可怕;
  2. 在开发中是不可避免的;
  3. 但可以通过合理的代码结构和任务分工尽可能地规避冲突;

冲突可能由以下几种情况导致:

  1. 不同的功能分支在并行开发阶段中冲突修改了同一块内容;
  2. 不同的功能分支在并行开发阶段中合并入master分支有前有后,导致功能分支在合并前可能已经落后于master过多;
  3. 当某个PR发生冲突时,Bitbucket中将无法合并,一般在本地通过merge追平目的分支或手工解决冲突后再push即可;
  4. 请注意:SVN Mirror时,在某些情况下现在版本的Bitbucket不能正确地跟踪文件删除,将导致合并时被删除文件又出现,因此建议尽快统一迁移至Git;

C:\Users\mlkui\AppData\Local\Temp\WeChat Files\04e39b8a6eded0a7408677c39b452fc.png

三、示例

以下以“在某名为EXAMPLE的业务中台系统中增加一个名为limit的模块”这一大功能点进行示例:

  1. 大功能点准备开发时,从master分支创建limit模块对应项目分支,project/EXAMPLE-limit0821;
  2. 将limit模块的功能点拆分为若干个Jira任务,如EX-123到EX-234;
  3. 开发人员neilinju按照分配,开始进行某个任务,如EX-123的开发,在Jira中直接创建对应任务分支,task/EXAMPLE_limit0821_neilinju_EX-123-feature1;
  4. 开发人员fuqi按照分配,开始进行某个任务,如EX-124的开发,在Jira中直接创建对应任务分支,task/EXAMPLE_limit0821_fuqi_EX-124-feature2;
  5. 开发人员yangyu按照分配,开始进行某个任务,如EX-125的开发,在Jira中直接创建对应任务分支,task/EXAMPLE_limit0821_yangyu_EX-125-feature3;
  6. 开发人员mei按照分配,开始进行某个任务,如EX-126的开发,在Jira中直接创建对应任务分支,task/EXAMPLE_limit0821_mei_EX-126-feature4;
  7. 当task/EXAMPLE_limit0821_fuqi_EX-124-feature2开发完成时,开发人员fiqi提交PR,请求将task/EXAMPLE_limit0821_fuqi_EX-124-feature2合并至大功能点对应的project/EXAMPLE-limit0821分支中;
  8. 此PR若要合并,需要满足项目组的评审要求(交叉评审、分级评审等),并会经过多轮的Need Works后被最终Approve,并Merge到project/EXAMPLE-limit0821中;
  9. task/EXAMPLE_limit0821_neilinju_EX-123-feature1、task/EXAMPLE_limit0821_yangyu_EX-125-feature3、task/EXAMPLE_limit0821_mei_EX-126-feature4同理,走PR流程合并至project/EXAMPLE-limit0821分支中;
  10. 当unlimit模块开发基本完成时,将project/EXAMPLE-limit0821大功能分支通过PR或手工Merge方式合并入DEV分支(若是通过PR进行则可以进行代码评审),供DEV测试;
  11. 当进入UAT阶段时,将project/EXAMPLE-limit0821大功能分支通过PR或手工Merge方式合并入UAT分支(若是通过PR进行则可以进行代码评审),供UAT测试;
  12. 对于在DEV、UAT测试中发现的问题,依然通过PR提交至project/EXAMPLE-limit0821分支,并经由project/EXAMPLE-limit0821分支合并至DEV、UAT分支;
  13. 同理,直至project/EXAMPLE-limit0821合并入VER和master分支;

以上过程与基于SVN的流程不同在于:

  1. 通过鼓励使用轻量级分支在Jira任务粒度控制开发;
  2. Jira任务分支并入功能分支时,通过Bitbucket的PR流程实现了代码评审及全过程的溯源,从而将代码评审变成每个开发人员日常工作的一部分,避免了FishEye评审节点滞后、形同虚设的问题;
  3. 功能分支上DEV、UAT、VER、PRO时,通过Bitbucket可以缓解SVN手工扣代码或SVN重量级分支Merge带来的问题;

四、分支权限设置

请注意,我们在前面提到过,不使用SVN Mirror时为了后续自动化时根据分支名称表达式匹配推荐使用前缀方式的分支名称。通过Bitbucket的Branch pattern表达式可以看出,使用路径而非扁平的情况才可以方便地使用**来匹配一组路径,进而精细地控制各分支的合并权限、自动化手段等:

转载时请保留出处,违法转载追究到底:进城务工人员小梅 » SVN2GIT之路(四)基于Bitbucket的分支管理及代码评审实践

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址