网上关于Git-Flow的教程一大堆,哎呀,命令行太多记不住啊。还好有SourceTree,但是好像功能还挺多,不知道什么时候选择什么功能,新版的SourceTree和网上的教程的截图貌似对应不上。正好我最近也在学习Git-Flow,好记性不如烂笔头啊,光说不练假把式,我们开始吧。参考教程
一. 首先配置环境
前往SourceTree下载这个免费强大的Git GUI工具。安装过程略,你需要注册个SourceTree的账号。
本文基于SourceTree 2.5.1 mac版,Windows界面差不多。
如果你的电脑还未安装Git的话,首先得安装Git,同样安装过程略。mac用户建议使用HomeBrew来安装Git。Windows用户建议使用安装包来安装Git,这样会自动将git加入到环境变量中。
二. GitFlow
- 创建本地和远程仓库
创建好了会自动打开操作窗口
-
做第一次提交(确保至少提交一次到本地仓库,这样才会创建master分支)
如果不提交一次的话,GitFlow就无法初始化,因为其不知道以哪为基线(因为master分支尚未创建)。
这里我就在本地的Test文件夹创建个文件,然后在SourceTree的文件状态里对这个文件加入索引,再点击提交。
提交后就会发现分支有个master分支了:
如果需要重命名则点击菜单的“移动”选项
初始化GitFlow
注意:初始化操作需要在团队每位成员电脑上均进行一次,各配置需保持一致.应由仓库管理员创建仓库
按快捷键Command+Option+F 或者菜单 仓库——GitFlow——初始化仓库
如果在master分支上没有做任何提交的话,GitFlow是不会初始化成功的,会报错如下:
有过提交记录的master分支可以正常初始化git-flow
确定后会出来个develop分支
-
推送到远程服务器
注意只需要推送master和develop分支,如果你现在已经创建了feature或release或hotfix分支都不要推送,远端只需要master和develop.
-
新增Feature分支(功能)
老样子 Command+Option+F 打开GitFlow菜单,选择 “建立新功能”
输入新功能名称:
现在会创建feature,并自动切换到当前feature分支:
-
在新创建的feature分支中进行开发:
比如我这里添加了个新文件:
右击文件添加索引后提交:
提交后的状态如下:
此处省略一系列的开发提交过程。
-
完成feature功能开发
点击“完成当前版本”按钮,弹窗如下:
这里主要讲下“在开发分支上进行变基”(rebase)这个勾选框,如果勾上则表示保留在这个feature功能上的提交历史到develop分支上,不勾选则合并这个功能模块的提交历史成一个(Merge某某功能到develop)。默认是不勾选的。一般使用默认选项即可。
发布release分支
release分支总是由develop分支发起
研发这个时候应该切回release分支,将这个分支上的代码编译然后部署到测试环境中供QA测试,这个时候团队一方面应该做代码ReView工作,一方面要响应QA那边反馈过来的bug,然后在这个release分支上做修复/修改工作。
例如我这里简单的提交一下:
当QA觉得OK了,代码ReView也通过了,那么就可以“完成发布版本”
“以此消息打标签”这里应该写详细的更新内容,比如新增了XXX,修复了XXX,优化了XXX等,不应该像我截图那样直接写个版本号在上面。
此时应该推送到远端仓库完成真正的发布:
远端仓库你应该能看到新发布的:
- hotfix 分支(紧急修复线上版本bug)
git-flow假定当前产品线只需要维护一个版本,所以Git-Flow的hotfix总是基于最新的master分支里的版本来开辟的。如果需要同时维护多个版本,那么就不应该用master分支了,可以多建几个分支比如1.x分支,2.x分支,3.x分支,这样就可以同时维护3个版本线的产品,但是所带来的维护量就变的很大了。所以建议大家只维护一个版本来做CI(持续集成)
Git-Flow的hotfix分支和release分支有点像,区别在于release分支是由develop分支拉取出来的新分支,而hotfix分支是由master分支拉取出来的新分支,两者最终都会合并入master和develop分支。只不过hotfix用于生产环境中的紧急修复,需要快速响应和修复,减少Code ReView和QA环节的时间(不是说不做,只是说尽量快点完成这两个环节,尽量快点修复,否则大批用户都会受这个bug影响,毕竟是生产环境。)
假如QA同学发现线上版本有个bug需要修复,他应该在Git的工单系统里把bug详细叙述了一下
注意issue后面的#1这是issue的代号。后面可以通过commit信息来关闭这个issue
回到SourceTree,切回到master分支上:
在这个hotfix上做bug修复,
如果你确定修复了某个issue,可以在提交信息中写fix #1 或close #1等信息来直接关闭某个issue。
修复完毕后,继续Command+Option+F 打开GitFlow菜单:
推送完毕后,我们来看看网页:
大家有没有注意到issue已经被关闭了,在release那里也能看到新发布的版本。
三. 总结
- GitFlow有5大分支:master(主干)、develop(开发)、feature(功能)、release(预发布)、hotfix(热修复)。这里说下release分支,其实正名应该叫发布分支,我为什么叫他预发布分支呢,因为这个release分支并不是真正的发布,他是由develop分支经过多次feature功能迭代后分出来的一个分支,告诉大家这些功能准备的差不多了,可以准备发布了,但是实际上并没有发布。release分支创建好后,应由QA做测试,研发一起联调,然后先发布到测试环境中进行测试,QA如果觉得有问题,可以先提交工单给研发,研发在这个release分支上做小幅度bug修复,如果QA觉得可以使用的时候再由研发完成发布功能,此时release分支上所做的更改会被合并入master和develop分支中,release分支会在合并后被删除。
-
master
定义:生产环境分支
作用:记录每一个正式发布版本,TAG所在分支
合并关系:允许release\hotfix分支的合并
建立时机:仓库初始化
初始代码来源:仓库创建- develop
定义:开发分支
作用:保持最新的开发代码
合并关系:允许feature\release\hotfix分支的合并
建立时机:master创建完成
初始代码来源:master- release
定义:发布分支
作用:表示一个正式发布版本(我更倾向于叫他预发布)
合并关系:不允许任何分支合并
建立时机:线上代码满足发布要求
初始代码来源:任意线上commit,推荐使用develop最新commit
完成操作:合并至master/develop、打相应的TAG- feature
定义:新功能分支
作用:独立的功能需求
合并关系:不允许任何分支合并
建立时机:需要开发新的功能
初始代码来源:任意线上commit,推荐使用develop最新commit
完成操作:合并至develop分支- hotfix
定义:修复BUG分支
作用:用于修复已发布版本BUG
合并关系:不允许任何分支合并
建立时机:发布版本出现BUG
初始代码来源:master(source tree 没有提供历史发布版本的hotfix创建,如需要可手动操作)
完成操作:合并修改内容至master/develop分支
- 远程仓库仅仅应该存在两个分支,一个是master分支,存放线上(生产环境)版本,这个分支的代码总是可靠可用的;另一个是develop分支,这个分支用于日常开发。
- 本来master分支上的内容不应直接提交(除了第一次初始化GitFlow前需要至少提交一次在master分支上,确保master里面有内容),master分支总是应该由develop分支发布到release分支,经过QA测试确认可以上线后(期间可以在release分支上进行小幅bug修复提交更改),再完成发布新版本功能然后合并入master分支(发布成功后release分支会被删除,在release分支上所做的更改会自动合并到master和develop分支上)。但是如果在GitFlow已经初始化后(develop分支已经有了)不小心在master上直接提交了新的commit,这会导致develop分支上缺少主干master分支上的内容,这个时候就需要先将master分支推送到远端,然后本地切回到master分支,然后再使用pull功能从master分支上拉取内容到develop分支(SourceTree会警告正要从未跟踪的分支上拉取内容,点继续),这样就把master上所做的更改来回到develop分支上了。 虽然有这个曲线救国的办法,但是平时在使用的过程中还是要注意规范,尽量避免这种情况。
-
feature 分支 下可以有多个feature同时在开发,并不影响。feature最终是提交到develop分支上的,release是从develop分支上拉取的,release分支是提交到master分支上的(develop分支不能直接提交到master上),他们几个并不冲突。允许在仍然有feature在开发的情况下从develop分支拉取到release分支。
-
如果建立了某个开发功能(feature)或者发布版本(release)分支后,如果不想开发或者发布了,可以先切回到其他分支(比如master或develop分支),然后在要删除的分支上右击,选择“删除分支”
-
讲下如果线上发布版本的内容或者版本号写错了,在网页上直接删除即可。
例如我这里的“fixLoginBug”应该填写的是“1.0.1”版本号,但是当时提交的时候却写错成修复内容了。
删除即可。删除完了记得会SourceTree里Pull 拉取远程仓库的更新内容到本地。 - 本文为了演示方便,提交信息以及发布日志(更新内容)极不规范,实际开发中应该规范提交信息,在大方面做到尽可能的详细。请参考这个commit模板
例如,
fix: Add TimeUnit null check test case in Timed #5231
* Add TimeUnit null check test case in Timed
* Correct ugly formatting in BasicIntQueueDisposable
* Reformatting line
* Add blockingIterable’s negative buffer size fail test,close #5232
* Modify BlockingMultiObserver field’s modfier to private,fix #5231
* Revert style, modifier
* Remove duplicated test case.
* Remove no need annotation and variable
标题总结了此次提交的主要改动的主题(如果此次提交涉及或者修复了某个issue,建议在标题里用#来引用这个issue,如果是确认修复了这个issue建议在提交信息使用fix #222 或者close #222 来自动关闭对应的issue),然后在下面详情里每一行阐述具体改动了什么(或者说为什么要这么改)(为了修复XX,增加了XXX,重构了XXX,修改了XXX,移除了XXXX)每一行最好以常用动词开头。
- 多人协作的时候,应由仓库(项目)管理员来创建master分支并在本地初始化好GitFlow后一并将master和develop分支推送到远程仓库(master分支默认有写保护,只有创建者才能写入推送,其他协作者只能pull拉取)。其他协作者将项目克隆下来,同样要记得初始化GitFlow,注意配置要保持一致。其他协作者在本地完成feature开发,然后推送到develop分支,由项目管理员来负责发布release分支和发布新版本