代码不会骗人,是决定交付质量和交付速度的重要因素。能否借助技术管理工具、技术管理机制和技术管理手段做好源码管理,是实现良好架构、良好设计,保证顶层思想顺利落地重要前提。
针对目前我中心内部代码评审工作开展乏力的情况,可以考虑使用采购的Atlassian系列产品中的Bitbucket,推动使用基于Git和Bitbucket的现代化源码管理和评审工具替代此前的SVN+FishEye,从部分有能力的项目组开始、选择部分工程、开始小规模向Git+Bitbucket的现代化源码管理和评审工具上迁移,从而在过程控制层面充分利用现有的人员实现能够有效落地的分级评审和交叉评审。
项目的交付质量在很大呈上在于代码质量,而代码质量的把控在相当程度上是借助源码管理和源码评审实现的。目前,我中心绝大部分项目组使用SVN+FishEye作为SCM和评审工具,已经是上一个十年的产物,在一线大厂早已在事实上被淘汰,已经无法适应目前现代化的开发和迭代交付要求,不足以应对当前我们项目开发中迫切需要的分支管理、分级代码评审(小组长先评审,待小组长评过后技术经理审等)和交叉代码评审(某个功能开发小组内部交叉评审后再提给小组长审)的要求。建议部分有能力的项目组、选择部分工程、开始小规模向Git+Bitbucket的现代化源码管理和评审工具上迁移,从而在过程控制层面充分利用现有的人员实现能够有效落地的分级评审和交叉评审,解决目前代码评审难以落实的问题,以达到切实从根本上提高代码开发质量的目的。
由于SVN在分支管理方面存在的硬伤,以SVN为核心的上一代源码管理工具在很大程度上具有相当的局限性,影响了我们的开发质量和交付速度:
- 无法实现高效的分支管理。SVN的分支管理是重量级的,基于文件的物理复制;而Git的分支是基于改变的轻量级分支,不基于物理文件的复制;
- 人肉合版低效、不经济、易出错。低效的分支管理导致了大量项目组在分支合并时不使用Merge而只能依靠Araxis Merge、Ultra Compare、Beyond Compare等文件比较工具,由项目组中某个关键人进行人肉手工合版,在上UAT、VER、PRD时均需要多次手工合版,此种行为是低效、不经济、易出错且可以完全被自动化替代的;
- SVN分支管理粒度过大。由于SVN固有的物理文件分支粒度过大,往往不是某一个小功能级的,不利于将某个待上线的大功能分解为能够由多个或多组开发人员并行开发然后逐步评审、逐步合并的小分支,导致某一个功能分支向DEV、UAT等分支合并时时机过于延后,从而导致出现冲突的概率较大,也非常不利于代码评审工作的开展。
- SVN无法应对实际开发中复杂的分支管理场景,尤其在投产周期和测试过程严格受控的环境中。由于SVN的分支合并后往往原分支将被删除,即丢失了原有分支分支中的提交记录,因此很难应对诸如某个功能延期投产导致需要剔除部分已合并代码的痛苦场景;
- 代码评审形同虚设。即便是引入了FishEye等评审工具,由于功能分支合并入DEV、UAT分支的时机非常靠后,往往是临上线前在合并入DEV、UAT分支时才提交的评审,而评审人又通常直接被指定为项目经理,项目经理往往又根本没有时间和精力去看代码,且此时待并入的代码往往已经进行了一定程度的测试,如果评审拒绝后再进行修改又要面临回归,因此在事实上根本起不到控制代码质量所最为关键的分级代码评审(小组长先评审,待小组长评过后技术经理审等)和交叉代码评审(某个功能开发小组内部交叉评审后再提给小组长审)的作用,掩耳盗铃;
目前,Git由于其一系列显著优于SVN的理念和特性,不管是开源世界还是工业大厂早已将其作为一线源码管理工具;而采购的Atlassian系列产品中(Confluence+Jira)也包含了Bitbucket,从而为推动使用基于Git和Bitbucket的现代化源码管理和评审流程提供了可能。
SVN是上一个十年中被大量使用的集中式版本控制系统,在其中保存了所有文件的修订版本,其分支实际是被复制到独立物理路径中的物理文件;而Git则是分布式版本控制系统,其通过元数据记录被管理的文件是否发生变化,在本地磁盘上保存了所有当前项目的历史提交:
与SVN基于物理文件的重量级的分支不同,Git的分支是轻量级的,通过元数据管理在创建新分支时只记录发生变动文件的变动记录,而不是将所有文件全部复制一份。Git最初是为了针对数千人参与的Linux开发团队而设计,意图解决大规模开发时政治、流程、人员和技术的问题,鼓励大量使用轻量级分支,奠定了当今包括GitHub、GitLib等开源协作社区的基础,同时也是解决敏捷开发和大规模协作所面临各类问题的重要基础工具:
Bitbucket是Atlassian系列产品中的一员,可以与Jira等无缝集成,可以认为是GitHub等Social coding平台的企业版产品,目前已有部分项目组出于主动或被动地原因在使用。下面通过几个典型的场景,展示为何建议部分有能力的项目组、选择部分工程、开始小规模向Git+Bitbucket的现代化源码管理和评审工具上迁移,从而在过程控制层面充分利用现有的人员实现能够有效落地的分级评审和交叉评审。有关Git分支管理模型有多种,在此暂时不讨论,只概要性地介绍几条优于SVN+FishEye的优势:
一、与Jira无缝集成,Jira任务可直接建立对应Git功能分支并方便地跟踪
在Jira中对Jira任务可以直接已某一远程分支为base创建对应Jira任务的分支,且可以通过Repository配置的分支模型创建包括feature、bugfix、hotfix在内的不同类型的分支:
诸如bugfix和hotfix等缺陷修复分支可以根据策略自动化合并至某些主干分支中,从而避免线上缺陷修复等时向多个环境或开发分支中的手工合并。
同时,Jira任务与对应Git分支的管理能够有效、真实、精确地反映每个开发人员对此任务的提交,而不同于SVN提交时手工在Message中简单地增加Jira任务号的粗放管理方式。
二、良好的多分支管理及完整的PR流程
对于SVN而言,多分支和并行开发是痛苦的,且由于单个开发人员代码必须物理提交到中心服务器上,导致代码评审过程也难以进行。而对于Git而言,多分支管理则是轻量化和无痛地,我们可以在一个Repo中从Jira任务的维度或自定义的维度开出无数的分支:
作为分布式管理系统,每一个开发人员在本地可以开单独的分支进行开发,当开发完成后再通过PR(Pull Request)提交将本地分支合并至某一远程分支,此过程中可以由可选的多个reviewer进行代码评审(Approve、Reject),直至评审通过后才可并入对应的分支:
三、友善且可反复进行的、灵活的Code Review
在Bitbucket的PR中,可以方便地看到每一个文件的改动及历史commit记录,并可针对每一个文件存在问题进行commit,并最终Reject,由PR者进行修改、再次PR、再次Review,直到满足Reviewer的要求后Approve,并在Approve的Reviewer数量满足要求后,PR者才可将分支Merge:
例如,如下的PR在经过两个Reviewer通过后,合并到了主干分支:
而每一个历史PR都是可以追溯的,代码评审不再是某一个项目关键成员、技术经理或项目经理的责任,而是可以在机制上通过交叉评审和小组长评审实现,让全部开发人员参与到代码评审工作中:
这样,也就为我们目前所有项目组都不容易落地的、控制代码质量所最为关键的、分级代码评审(小组长先评审,待小组长评过后技术经理审等)和交叉代码评审(某个功能开发小组内部交叉评审后再提给小组长审)提供了可能。通过在项目设定分层级的评审流程,例如:某三个开发人员先提给管理其的小组长,或在没有小组长的情况下提给其他的共同开发人员进行交叉审核,待审核通过后直接并入对应的大功能分支、甚至UAT等主干分支,或由小组长继续负责PR给技术经理审核,从而在机制上就强制性地将代码评审工作变为了日常开发工作的一部分,能够从机制上彻底解决此前FishEye评审阶段过于滞后且项目经理根本没有精力审核只能全部无脑点过的严重问题,实现在开发阶段早期、本地开发完成尚未进入到测试阶段时就充分地利用每一个开发人员进行Code Review。
以如下的一个PR为例,前期有两位Reviewer指出了某段代码存在的问题,并阻止了改PR的合并(NEED WORKS),在另外的开发人员进行了修改,并最终得到一个Reviewer的Approve后才得以合并:
四、良好的冲突管理
在日常开发中,合并冲突是不可避免的,不管是SVN还是Git都不能自动地解决冲突问题。但SVN在解决冲突时是较为痛苦的,而Bitbucket中应对冲突时则较SVN容易一点:
五、支持多种Git分支管理模型及某些层面的自动化
我们可以在Bitbucket上定义多种分支模型,例如可能包括多个功能开发分支、一个开发分支、一个发布分支、一个hoxfix分支及一个主干master,通过借助PR能够保持在上述多个分支的良好迭代,并通过评审过程保持关键分支的稳定。对于诸如bugfix等还可以通过自动化合并策略将其合并到合理的分支中,这些都是SVN不可能具备的能力。
例如,合并前检查:
转载时请保留出处,违法转载追究到底:进城务工人员小梅 » SVN2GIT之路(一)引言