前言
Git等版本控制工具最核心的使命是:
确保数据安全性和完整性。
提升团队协作效率。
但是如果分支管理不规范,这两点都可能得不到保障。
Git-Flow分支管理模型
自Linus Torvalds 2005年发布git以来,如今git早已一统江山,但git的分支管理却大相径庭,各有各的玩法。但其实2010年,就有一哥们(Vincent Driessen) 提出过一个git分支管理模型——Git-Flow,可以非常好的应用于发布频率稳定、需求明确的项目!
直接上图(上网一搜git-flow,可以发现这图其实都包浆了):
这个图就是Git-Flow的分支管理模型,从图上可以看到,涉及的分支有:
master
:主分支,也是发布分支。所有提供给用户使用的正式版本,都得在这个分支上发布。develop
:开发分支。代码最新。feature-*
:功能分支。正在开发的新功能,未必确定上线版本。通常*
的值对应issue key
或者jira key
。release-*
:测试版本分支。提测分支,通常*
的值对应一个版本号,表示是这个版本的内容。hotfix-*
:紧急修复线上bug分支。通常*
的值为当前线上版本号的修订版本+1(版本号规则:x.y.z,即z+1)。
其中,master和develop是长期固定的分支!其它都是从这两个分支创建出来的,最终要回到这两个分支,并被删除掉。
演练下
假设,现在有一个hello-world项目,目前发版频率稳定,每周三发版,每周四需求评审确定下一版本内容——即从需求池中拣选需求/缺陷归入到下一版本。
同时部署环境依然是常规的开发、测试、正式。
那么具体怎么按照Git-Flow的分支规范来践行呢?
比如现在线上版本是
2.0.2
,接下来要上线的版本是2.1.0
:
周四:需求评审后
需求评审结束,即确定了下个版本的内容,比如jira上的A~G 一共7个需求。此时相关开发人员应当先确定自己是否之前就完成了A~G的需求开发。例如张三早已完成了C的开发,那么应当已经存在分支 feature-c
(无论这个分支在张三本地还是在仓库),此时张三应当将feature-c
合并到develop
,并删除feature-c
。然后团队开发人员都在 develop
上(团队成员少时),或者从develop
拆分个人分支(团队成员人数多时) 进行A~G需求的开发。
develop
应当集成开发环境,方便开发人员自测。
周四:下班前发现效率不错,已经做了2个需求了!准备先提测一波
总不能等A~G全开发好再提测,这样往往预留给测试人员的时间会非常紧。实际中,往往是覆盖式推进。于是,某个开发人员(往往可能是开发leader) 从develop
checkout出了 release-2.1.0
。
release-*
应当集成测试环境,以便测试人员测试。
如此,已经做好的A、B便可以由测试先行测一波了。
周五:线上环境出现bug,需要紧急修复
线上出问题了,需求紧急修复。开发人员应当从主分支master
创建一个 hotfix-2.0.3
(线上分支的修订号+1),并修复此缺陷,然后将 hotfix-2.0.3
合并到master
触发线上构建,然后再将 hotfix-2.0.3
合并到 develop
,最后记得删除。
如果此缺陷影响当前版本
2.1.0
的测试,还需要合并到release-2.1.0
。master分支记得打一个
2.0.3
的tag!
次周一:已经发布到测试环境的A测出了问题
张三写完A需求没有自测,或者自己没测出问题,被测试测出来了。这时张三应当在release-2.1.0
修复A,推送触发构建到测试环境,并将release-2.1.0
合并到develop
,然后继续手头当前版本的其他需求。
张三手头上还在干的C、D应当继续在
develop
上开发。
次周二:当前版本需求已经全部完成
应当将develop
及时合并到release-2.1.0
,并提交正式的提测申请。
此时,在下一个版本评审结束前,所有的开发工作都不会在develop
分支上进行。如果是2.1.0
测出来的问题,则直接在release-2.1.0
上进行修复并更新到测试环境;如果是需求池的其它需求,还不确定版本,则从develop
新建feature-*
分支开发。
虽然明天就要发版,看似预留给测试的时间不多,但由于是覆盖式推进,
2.1.0
版本中的很多需求测试可能都测完了。剩下的一天只需要系统性的回归下即可。
周三:测试通过,发版上线!
测试人员一旦完成测试,则开发人员应当将release-2.1.0
合并到master分支!同时也合并回develop
分支,并记得删掉此分支。
master
分支可以集成正式环境,进行持续交付。master分支记得打一个
2.1.0
的tag!
如此,便完成了一个版本迭代的整个过程!
运行良好。
有没有别的插曲?
Git-Flow这个机制目前看运行的很好,但如果发生以下问题呢:
1. 某个需求中途不上了
版本开发进行到周五,PM忽然说,A需求这个版本不上了!都开发完了,测试环境也都部署了。
首先,这种情况不能是常态!这只能说明PM对版本的把控能力不足。但实际中依然受不可控因素影响导致发生。这时如何解题?
如果A对应的提交尚未提测到
release-2.1.0
,则直接在develop
上git revert
即可;如果已经提测,则直接在release-2.1.0
上git revert
即可。同时别忘了,将A的提交
cherry pick
到feature-A
,以备下次上线需要。
2. 某个需求feature-* 分支如何自测呢?
在上面的分支管理规范中,如果某个需求Z还没有排版本,但是开发完了想自测,是不能合并到develop
的。
这种情况只能自己本地自测下了,如果涉及到数据库脚本的大量改动,可能还得有本地库才行。总之记住的原则就是以后的需求(非接下来版本的)不要贸然往
develop
上合。
小结一下
Git怎么用,不是选择题,也不是判断题,没有标准解。如果项目很小,亦或是团队成员很少。就简简单单的 develop + master
也可以,甚至我个人的一些小项目,像小程序小应用,就只有一个master
。
只能说,适合自己团队的就是最好的,如果当前团队中没有自己的规范,或者虽然有但仍然存在混乱等问题,可以尝试下Git-Flow
这套玩法。
特别值得注意的是上面记录的Git-Flow和标准的Git-Flow还是有点区别的,主要体现在:
分支命名不同,上面提到的 -*,标准Git-Flow是/*,例如
release-2.1.0
, 标准命名可能是release/2.1.0
标准的Git-Flow 在
feature-*
分支开发完应当直接合并develop
,这可能更适合非业务系统,或者功能的上线次序,遵循的是先做先上。但是国内很多业务系统,团队管理模式下,可能出现需求池,排期,开发超前做等情况,因此标准的可能不太试用。
参考
A successful Git branching model —— 就是Git-Flow提出人(Vincent Driessen))发表的
介绍一个成功的 Git 分支模型 —— 上面的译文版