Blog: https://micleming.github.io/
在开发一个中大型项目中,团队工作流程的建立必不可少。对应于某个产品,从初始时的产品需求收集、分析、建模到交互设计,视觉设计,再到开发团队的开发和测试团队对交付的产品进行测试,最后再进行上线,以及对线上产品出现的问题进行快速修复。这些过程涉及到了多个团队,多种角色之间的合作。所谓的没有规矩,不成方圆。在团队和团队之间、团队内成员之间的合作制定一定的规范,由此形成了一套工作流程。一个合理的工作流程保证了产品从设计到研发再到上线不会出现过多的问题。而一个优秀的工作流程能保证不会出错的情况下提升研发的效率。
对于研发团队(programmer), 最直接的是使用版本管理系统进行内部成员之间的协作。目前比较常用的是基于SVN
和GIT
来对代码进行管理。越来越多的项目由SVN
切换到GIT
, 所以接下来将基于GIT
来讨论研发团队工作流的建立。
在项目的研发过程中,基于git
源代码的管理一般会面临下面几个问题:
这几个问题并非是各自独立,对一个问题的解决方案往往会影响另一个问题的解决方案选择。
对于一个产品,在上线之前会有不同的环境,用来发布不同分支的代码以此来对代码进行充分测试。常见的环境分为:
online
:产品最终发布的环境stage
:产品发布前用来做最后验证的环境,该环境的数据库一般是线上数据,该环境在访问上做了限制dev
:开发过程中使用的环境test
:测试人员测试使用的环境不同的环境,发布时使用的分支也是不一样的。一个项目的一般会分为多种不同类型分支,常见的分类方式是将分支分为以下几种:
在对于master
分支,对应的是运行在线上机器的代码,但是上线的时候,并不一定是利用master
分支进行上线。dev
分支是发布到dev
和test
环境的分支。hotfix
分支是用来处理线上紧急问题的分支。feature
分支是用来开发特定功能的分支。
分支上线是在开发时,从master
分出一个分支A
,在上线的时候是将A
分支代码进行上线,然后将A
分支代码合并回master
。这种策略保证了在同一个项目同时开展多个迭代时的冲突问题,但是需要在上线的时候保证分支A
上合并的master
代码是最新的代码,否则你可能会把别人上线了的功能下线的(:, 而且在上线之后需要将分支A
合并回master
,否则下次上线的时候会把这次上线的功能下线掉(:
主干上线是利用master
分支进行上线,线上的代码就是master
上的代码,当代码达到上线标准之后,便将代码合并到master
进行上线,新功能的开发也是基于master
上的代码进行开发。所以在如果基于管理方便的角度上,主干上线的方式是比较推荐的方式。
基于主干上线
的方案下,该如何对分支进行管理又是一个值得讨论的问题。对于一个项目,在一个时间阶段,可能仅仅只有一个迭代在进行,但是也有可能有多个迭代在同时进行。
在只有一个迭代的情况下,我们可以按照典型的git工作流做适当删减进行管理,在分支类型上,我们可以做如下规范:
在流程上,我们可以做如下限制:
通过这些规范,仓库代码的master
和dev
保持了一致, stage
和production
环境使用的代码时同一份。
以上流程只适用于单迭代情况下,但是一旦涉及到同时进行多个迭代时,便会出问题。
在同时进行多迭代
情况下该如何进行工作流管理?
很自然的我们会想到对多个迭代进行区分,于是形成了这样的分支方式:
这样我们依然保证整个项目只有一个master
, 这个分支的代码和线上代码一致。每次新开发一个迭代,这种方式的规则如下
master
上checkout出一个新的带有迭代标签的[迭代]-dev
分支。[迭代]-feature
分支从[迭代]-dev
分支中拉取,[迭代]-feature
分支便是开发功能的分支,最终需要合并到[迭代]-dev
[迭代]-dev
分支由于是发测试机器,那么可能存在脏代码,所以有了[迭代]-stage
分支,这个分支从master
代码拉取,在测试没问题后再合并到master
分支,这种方式也方便处理迭代在最后阶段忽然不上线的意外情况发生,防止去回滚master
而可能会造成对开发别的迭代的人员的影响。hotfix
分支因为是对突发问题的处理,所以应该于独立于迭代,不会放到迭代中进行处理。通过这种方式似乎可以比较可靠的解决在同一个项目同时进行多个迭代的情况。
但是,却会出现一个问题,那就是:分支这么多,管理起来变得麻烦。
所以,对于较少出现的意外情况,在流程管理过程可以作为特例来处理,比如两个迭代同时上线的情况。这些特殊问题可以放到更高纬度的项目管理中去,比如和PM进行约定不要在同一时间上线。
那如果不对这些较少出现问题进行考虑,重新设计多个迭代的代码管理流程的话便比较轻松。和单个迭代类似,我们有如下分支:
几个不同点的是
feature/main
在往dev
合并代码的时候,并非是合并,而是覆盖
代码。由此防止带上别的迭代的代码。feature/main
分支需要直接从master
拉取。然后在此基础上分出相对应的feature[1~N]
,feature[1~N]
在开发完后也需要合并回feature/main
这个方案的工作流程是:
master
拉取一个迭代主分支feature/main
(迭代的区分可以加前缀,这里不细说)feature/main
拉取不同的feature
分支feature/main
,本地测试没问题后将feature/main
覆盖到dev
,发布到机器上dev
合并到master
,发stage环境的机器stage
环境没问题的话就发线上机器
其余和单个迭代时的分支管理是一致的。
通过这种方式,便能较简单的在同一项目进行多个迭代的情形进行管理。做出工作流程的目的是为了在多人合作的情形下提高开发效率,减少错误的发生,虽然可能会牺牲灵活性,但是从长远看,是有很大价值的。