第八章:利于集成的分支策略

版本控制系统的使用目的:
  用于存储及追踪目录(文件夹)和文件的修订历史(这里的修订操作包括3类:新增、修改和删除),从而让你能够回溯那些被纳入其管理范围之内的任意对象的任意一次修订。
  集中式版本控制系统:有一个单一的集中管理的版本控制管理服务器,典型代表SVN
    有两个缺点:
      在网络环境不佳的情况下同步大量文件时会经常失败
      集中式版本服务器具有单点故障风险
  分布式版本控制系统:多个服务器共存,每个人的节点就是一个代码仓库,所有的节点都是平等的。在团队协作过程中,通常会指定某个节点作为团队的中央服务器。典型代表是GIT
    特点:提交操作都是在本地进行而无须经过服务器,因此提交速度更快
  版本控制系统中的基本概念:
    代码仓库(codebase):指一个包含一组文件所有历史修改信息的逻辑单位,通常用于保存有关一个软件产品或某一组件的所有文件信息记录。
    分支(branch):指对选定的代码基线创建一个副本。人们可以对这个副本中的文件进行操作,而这些操作与原有代码基线的文件操作是互不影响的。
    主干(trunk/master):一个具有特殊意义的分支,通常在创建代码仓库时即由版本控制系统默认创建,每个代码仓库有且仅有这样的一个分支。其特殊意义在于其与软件的开发活动和发布方式紧密关联。
    版本号(revision):对应在某个分支的一次提交操作,是系统产生的一个编号。通过这个编号,你可以获取该次提交操作时点的所有文件镜像。
    标签(tag):某个分支上某个具体版本号的一个别名,以方便记忆与查找。你可以通过版本控制工具自身提供的命令来创建这个别名。
    头(head):指某个分支上的最新一次提交对应的版本号。
    合入(merge):指将一个分支上的所有内容与某个目标分支上的所有内容进行合并,并在该目标分支上创建一个新版本号。
    冲突(conflict):指在合入操作时,两个分支上的同一个文件在相同位置上出现不一致的内容。通常需要人工介入,确认如何修改后,方可合入目标分支。
    依据上面的定义,通过下面的字串记录方式可以唯一确定某个代码镜像:
    {代码仓库名}:{分支名}:{版本号}或者{代码仓库名}:{分支名}:{标签}
常见分支开发模式:
  主干开发,主干发布
    工程师向主干上提交代码(或者每个分支的生存周期很短,如数小时,或少于1天),并用主干代码进行软件交付
    根据交付频率不同,可以分为低频交付和高频交付
      低频交付:常见于一些周期比较长的大型软件开发项目,以数年或数月为一个交付周期。其主干代码总是长时间处于不可用状态,只有在项目内所有功能的代码开发完成后,才开始进行软件联调和集成测试工作。在开发期间,版本控制系统的作用仅仅是确保代码不丢失,是纯粹的代码备份仓库。
      高频交付:代码库中的代码发布频率较高,通常每天都会发布一次,甚至多次。常见于具有比较完备的交付基础设施(自动化配置构建、自动化测试、自动化运维、自动化监控与报警等)的互联网产品团队,通常也有快速缺陷修复能力,尤其适用于后台服务端产品形态(如Web网站或SaaS软件的后台服务)
    优点:分支方式简单,分支管理工作量较少(如代码合并成本)
    缺点:
      低频交付模式:
        项目后期的缺陷修复阶段,并不是团队所有人都需要做缺陷修复,会有一定的资源浪费
      高频交付模式:
        由于多人向主干上频繁提交代码,其代码变动非常快。假如某个开发人员拉出一个私有开发分支,并在该开发分支上进行开发,开发完成后再合并回主干。他有两种工作方式,一是每天从主干上更新代码到他自己的分支上。此时该开发人员很可能每天需要一两个小时将主干上的代码与自己分支上的代码进行合并。二是不做每日更新,一段时间之后,再向主干合并。此时可能由于主干上的代码变化太大,无法再合并回去
        高频交付模式下很难遵守“未开发完成的功能代码不能带入将要发布的版本里”
  主干开发,分支发布
    具体操作方法:
      开发人员将写好的代码提交到主干
      当新版本的功能全部开发完成或者已经接近版本发布时间点的时候,从主干上拉出一个新的分支
      在这个新的分支上进行集成测试,并修复缺陷,进行版本质量打磨。当质量达标后,再对外发布该版本
    特点:
      主干代码提交活动频繁,对保障主干代码质量有较大的挑战
      分支只修复缺陷,不增加新功能
      新版本发布后,如果发现严重缺陷,而且必须立即修复的话,只要在该版本所属的分支上修复后,再次发布补丁版本,然后将分支上的修改合并回主干即可。也可在主干上修复缺陷后,然后将针对该缺陷的修复代码挑出来(cherry-pick)合并到该缺陷所在的分支上
    质量打磨周期:在该模式下,从拉出发布分支开始,到分支代码达到可交付状态的时间周期可以作为评估主干代码质量的指示器。打磨周期越短,说明主干代码质量越好。当打磨周期极短时,可以转换到高频的主干开发,主干发布模式
    优点:
      与将要发布的新功能无关的人员可以持续工作在开发主干上,不受版本发布的影响
      新发布的版本出现缺陷后,可以直接在其自己的版本发布分支上进行修复,简单便捷。即使当前开发主干上的代码已经发生了较大的变化,该分支也不会受到影响
    缺点:
      主干上的代码通常只能针对下一个新发布版本的功能开发。只要新发布的版本的任何功能在主干上还没有开发完成,就不能创建版本发布分支,否则很有可能影响下一个发布的开发计划,开源项目在发布时间点以及特性功能方面的压力小一些,因此常常采用这种分支方式
      使用这种开发模式,对发布分支的数量不加约束,并且分支周期较长,很容易出现“分支地狱”倾向,这种倾向常见于“系列化产品簇+个性化定制”的项目

  分支开发,主干发布
    具体操作方法:
      团队从主干上拉出分支,并在分支上开发软件新功能或修复缺陷
      当某个分支(或多个分支)上的功能开发完成后要对外发布版本时,才合入主干
      通常在主干上进行缺陷修复,质量达标后,再将主干上的代码打包发布
    优点:
      在分支合并之前,每个分支之间的开发活动互相不受影响
      团队可以自由选择发布哪个分支上的特性
      如果新版本出现缺陷,可以直接在主干上进行修复或者使用hotfix分支修复,简单便捷,无需考虑其他分支
    缺点:
      为了分支之间尽量少受影响,开发人员通常会减少向主干合并代码的频率,从而推迟了发现各分支中代码冲突的时间,不利于及时进行代码重构
      分支过多,衍生出来的问题:当某个分支的生命周期(即从主干拉出分支的那一时刻至将其再次合入主干这段时间周期)过长,代码合并及验收成本会快速增加。成本增加的数量与其生命周期中合入主干的分支数量成正比
    想成功使用这种模式,关键点在于:
      让主干尽可能一直保持在可发布状态
      每个分支的生命周期应该尽可能短
      主干代码尽早与分支同步
      一切以主干代码为准,尽可能不要在各特性分支之间合并代码
    两种子类型:
      特性分支模式:
        概念:在开发过程中,允许多个开发分支同时存在,且每个分支对应一个功能特性的开发工作。当该特性开发完成后,立即合入主干,其他尚未合入主干的特性分支需要从主干拉取主干代码,与自己分支上的代码进行合并后,才能再合回主干
        目的:让团队更容易在“特性”这个层次上并行工作,同时保持主干的稳定可发布状态
        优点:每次发布的内容调整起来比较容易。假如某个新功能或者缺陷在版本发布时间点之前无法完成,则不必合入主干中,也不会影响其他功能的发布时间点
        缺点:如果特性分支过多,会带来比较多的合并成本。
        想让特性分支更好的工作:
          每个特性分支的生命周期都应该很短,分支上的开发和测试工作尽量在3天内完成。这要求尽可能将“特性”拆分为小需求
          开发人员每天从主干上拉取最新的可交付代码
          不要从其他特性分支上拉取代码
      团队分支模式:
        概念:团队分支可以看作是特性分支的一种特殊情况。一组人一起在同一个分支上进行开发工作,而且该分支上通常包括一组相近或相关的特性集合的开发。由于是一组特性集合的开发,因此其分支存续时间比特性分支的存续时间长
        适用场景:出现于规模较大的团队(40人以上)共同开发同一款产品,团队被分为多个组,每组开发不同的系统组件
        成功应用这种模式的关键点:
          每个团队尽早向主干合入高质量的代码,即使不马上发布
          向主干合入代码后,尽快使其达到可交付状态
          其他团队尽早从主干拉取可交付状态的代码,与自己分支上的代码合并
分支模式的演化:
  “三驾马车”分支模式
    概念:软件开发团队仅维护3个分支,分别是开发分支、预发布分支和发布分支
    开发分支:所有开发人员提交代码的目标分支
    预发布分支:只做缺陷修复、文档生成及与发布相关的工作,发布Alpha版本和Beta版本
    发布分支:发布正式版本
  Gitflow分支模式:特性分支模式和“三驾马车”分支模式的组合
    各分支介绍:
      Master分支是正式版本的发布分支
      Release分支是用于质量打磨的预发布分支。如果Release分支的质量达标,就可以将其合入到Mater分支,同时也需要将代码合入Development分支
      Development分支是对新功能进行集成的分支
      Feature分支是为了开发某一功能特性,开发人员从Development分支上拉出的分支。当特性开发完成后,合入Development分支
      如果已经发布的版本(如V0.1)出现了严重的缺陷,从Master分支上V0.1版本标签处拉出Hotfix分支,在这个分支上修复缺陷,验证后再次合入Master分支,并发布新的补丁版本V0.2.同时也需将修改合入到Development分支
    优点:每个分支的定义都明确且清晰
    缺点:分支较多,具有特性分支的不足
  GitHubFlow分支模式:
    工作步骤:
      从Master上创建一个新的分支,以这个特性或缺陷的编号命名该分支
      在这个新创建的分支上提交代码
      功能开发完成,并自测通过,创建Pull Request(PR)
      其他开发人员对这个PR进行审查,确认质量合格后,合入Master
    如果特性分支的存在时间很短,则该模式可被认为是高频的“主干开发,主干发布”模式

分支策略的选择
  版本发布模式:
    项目制发布模式:
      概念:在软件研发规划中,预先确定某一版本所需的功能特性数量,只有当该集合内的所有特性全部开发完成并且达到相应的发布质量标准后,才能发布该版本。前后两次发布时间间隔并没有明确的规定,而是在根据新版本要求的特性集合开发完成并达到发布标准后,对所需时间进行评估确定的。
      目标:针对一个特定版本,在确定了版本中的特性数量和质量标准后,再估计版本交付周期,这相当于固定特性数量和质量要求,那么团队可能的交付时间点也就相对固定啦
      优点:
        可以确切的知道每个版本包括哪些具体功能,有利于商业套装软件的售卖模式
        符合人们的安全生产习惯,即绝对不能把未完成的功能带到即将发布的版本中
      缺点:
        交付周期长
        参与人员众多
        在版本研发周期中由于某些原因发生需求变更时,需要重新确定交付时间,会影响那些原本能够按期交付的需求
    发布火车模式:
      常见于大型套装分发类软件
      大型传统企业通常有多条产品线,为了使各产品线协同发布,通常会为每条产品线都制订好每个版本的发布周期,即每个版本都像一列火车,实现计划好什么时间点发车。
      优点:对企业来说,可以通过并行多列火车的方式,将突发需求排入某一列发布火车。用户可以提前体验最新产品版本所提供的新特性,而不必影响原有生产线上正在使用的旧版本
      缺点:团队参与人数较多的话,沟通协调成本会较高
    城际快线模式:
      概念:在发布模式三要素中,固定其中的时间和质量两个维度,且时间周期相对较短(如一周,甚至一天或更少),针对那些在发布时间点已达到固定质量标准的特性进行一次发布
      优点:
        减少了团队及角色之间的协调成本
        每个人都非常清楚各个时间点
        更加聚焦于生产质量
      缺点:
        发布频率较高,因此未完成功能的代码也会一同发布出去
        对于代码提交质量的要求较高,需要强大的质量基础设施保障
        建议两周为一个版本
  分支策略与发布周期的关系
    一般情况下:
      软件开发周期极长的“项目制发布模式”团队、软件发布频率极高的“城际快线模式”团队使用“主干开发,主干发布”的分支策略(少于两周或超过半年)
      次之的团队会使用“主干开发,分支发布”的分支策略或“分支开发,主干发布”的分支策略
    持续交付2.0倡导城际快线模式
选择分支模式的原则:
  分支越少越好,最好只有一条主干
  分支生存周期越短越好,最好在3天之内
  在业务允许的前提下,发布周期越短越好

posted @ 2023-07-26 14:34  城南以南123  阅读(47)  评论(0编辑  收藏  举报