[TOC]
Git是分布式版本控制系统,与传统的集中式的版本控制系统相比:集中式分布系统必须联网才能工作。因为版本库信息都在集中在服务器上,你本地只是一个版本的代码,一旦服务器挂掉,所有人都停止工作,历史信息全部丢失【单点故障】。而git不会如此,每个人的版本库都是一个完整的仓库(它拥有中心版本库上所有的东西,例如标签,分支,版本记录),任何人的仓库clone到服务器即可。另外,在一个不能连接网络的地方时,就像在突然断网时,出差途中的火车、飞机上等,你仍然能够提交文件,查看历史版本记录,创建项目分支。
一、项目情况
烟草专卖,国家烟草总局统一全国推广,各省部署,且允许各地有自己的定制,个性化。
行业版:全国发包
特例版:全国22个省加直辖市加自治区,基于行业版代码,可以有自己的个性化定制。但是行业版升级时,所有特例版要跟随进行升级适配。
痛点:
行业+二十好几个特例需要分别打包管理,这么多的特例,行业升级适配,特例代码管理、版本控制等等想想都让人头痛。现实的情形确实也让人焦头烂额!所有的代码都用svn进行管理,且没有创建任何分支。刚开始行业版开发时还没有啥感觉,但是随着时间推进,特例代码的逐渐加入,越来越感觉力不从心。行业版发包、新功能开发、功能改造,特例开发、bug修正多任务同时并行,相互影响越来越大。
1、生产版本发布
没有分支管理,导致bug修复时,但因多任务并行提交,代码已经被多次更改,需要回退到历史代码再进行bug修复,回退时发现历史代码相互引用的位置也需要回退。以至于没有能力修复现场提出的bug,因为当前的代码已经面目全非了
2、 特例开发打包
所有代码基于行业版,为了实现定制化,把特例代码放到各省、直辖市简写的文件夹下,如北京 BJ、安徽AH、江苏JS等。随着特例的进一步增多,代码变得臃肿,所有代码冗余在一起。这样一来需要专门定制打包方案,把需要的代码打到一起,如北京:要把行业版+所有BJ文件夹打到一起,额外增加工作量,也比较容易出错。
此种情形下尝试引用git。
二、为什么使用git,git有什么特点
Git的分支与大多数版本控制系统形成了鲜明对比,其它的系统管理分支大多采取备份所有项目文件到特定目录的方式【重量级】,常常需要创建一个源代码目录的完整副本,所以根据项目文件数量和大小不同,可能花费的时间也会有相当大的差别,快则几秒,慢则数分钟。这是个昂贵的过程,对大型项目来说尤其如此。而 Git 分支的实现与项目复杂度无关,它永远可以在几毫秒的时间内完成分支的创建和切换。同时,因为每次提交时都记录了指向其父对象的指针(首次提交是没有直接祖先的,普通提交有一个祖先,由两个或多个分支合并产生的提交则有多个祖先)。Git 鼓励开发者频繁使用分支,正是因为有着这些特性作保障。如此看来,git十分适合解决上面项目的那些痛点
三、分支如何适配复杂应用场景
总览场景
SVN代码同步下来之后,去除其中所有特例代码作为行业版目前正在开发的主线分支master,将其用git管理起来。主分支是任何时候都不能删除的。辅助分支一旦到达某个稳定状态,合并完毕后是可以删除的,并且**hy-feature、hy-hotfix **这两个分支一般是本地分支,如下对这五类分支的特点做一一描述
1、行业版分支
行业版总共分5类分支
主要分支
master
hy-dev
3类辅助分支
hy-release
hy-feature
hy-hotfix
下面分别介绍各自特点:
master分支
主分支代表一个个版本,每次这个分支代码有变动,代表有新版本发布,有如下特点:
- 此分支可以随时打包;
- 所有行业版代码的正式版发包都由此分支来;
- master分支的每一次提交(合并)都是预先定义好的一个新版本,必须标识tag;
- 原则上不允许直接往此分支直接提交代码(jf上可以锁定此分支)。
开发分支-hy-dev
开发分支上永远是系统中的最新代码,代表整个系统的整体进度,此分支又称【整合分支】 - 普通开发人员的主要工作是基于此分支进行的;
- 行业版开发完成的特性(feature分支)必须合并到hy-dev分支;
- hy-dev分支上的代码达到了一个稳定状态,并且准备封包正式发布时,所有的代码提交都应该合并到master分支,然后打上发布版本号的tag。(也可以通过release分支合并到master)
辅助分支
在某个时间结点之后可以删除的临时分支
预发布分支-hy-release-xx.x
基于hy-dev分支的某个时间结点可以创建一个预发布分支 hy-release-xx.x
- 预发布分支只用于bug修复;
- Bug修复需要合并至hy-dev分支
- 随时合并至hy-dev分支
- 一旦稳定将同步合并至master分支(写tag),发布正式版本
功能分支(特性分支)
基于hy-dev分支创建功能分支(特性分支)hy-feature-功能1 - 此分支一般不需要推送至远程仓库上,除非需多人协作开发的功能
- 功能稳定后需要合并至hy-dev分支
紧急BUG修复分支
基于master某个tag创建hy-hotfix分支 - 本地管理不需要推送远程仓库;
- 紧急bug修复;
- 稳定后需要同时同步至master和hy-dev分支;
- 合并至master后会产生一个正式版本的小版本(tag)。
- 特例版分支中关乎行业版本的新功能或bug修复原则上也应创建类似hy-hotfix的分支进行修复后合并至master,再同步至特例版分支
2、 特例分支
更复杂的场景,行业版+特例版
全国各省都会有自己的定制化开发,这些也需要开发,测试,发包等一系列类似行业版的操作,且随行业版本升级而升级。特例版分支示例:如北京局特例版
北京局特例代码包含行业版代码+北京局特例代码,且这两者必须明确分开以方便后续行业版升级时的合并,为了降低复杂度,这个合并只能单方向进行,即由行业版分支合并至北京特利版分支,而不能将北京特例版分支中的行业更改合并至行业版分支,这样就要求所有北京特例版分支的所有开发操作只涉及北京特例内容,涉及行业版相关的代码需要在行业版分支进行。
特例分支创建
- 在行业版分支master基础上创建北京master分支bj-master
- 在bj-master基础上创建bj-dev
- 创建辅助分支bj-release1.1、bj-feature、bj-hotfix
注意:必须遵循一个规则:所有特例化的代码必须与行业版分离(如:单独文件夹,单独类名)。如此一来,当行业版进行升级时,所有的特例分支可以无冲突的快速与master进行合并。一旦不遵循这个规则,后续的分支合并,行业升级将十分痛苦,甚至无法合并!
看懂这个图,也就理解了这篇文章,基本可以应付各种复杂度极高的企业级项目代码管理了
3.2 小场景
行业功能开发过程中忽然需要进行北京特例2.2版本一个紧急bug的修复,此时行业功能刚开发一半,类还在报错不能提交,会影响其他人的工作。
此种场景在git中可以轻松+愉快的解决
用git stash命令进行快速切换
1
2
3
4
5
6
7
8
9
10 当前工作区工作暂存
git stash
切换至北京特例分支
git checkout bj-master
切换至跟生产部署的war包一致的代码环境
git ck tagv1.0
新建分支
git branch bj-fixbug-2.2.1
切换到新分支
git checkout bj-fixbug-2.2.1修复bug
提交测试
测试通过
合并分支
……完成了
1
2
3
4 切换到行业开发功能分支
git checkeout hy-feature-1.1
恢复工作区,暂存区内容,此时可以继续刚才的开发工作
git stash apply --index
大家可以想一下如果不用git,这个场景要如何进行
附录:
svn与git二者可以互相同步,但是要在.gitignore排除[.svn/] ,在svn中排除[/.git/]
建议:svn上对行业版、北京特例版、安徽特例版的代码进行区分。不要全部糅合在一起,这样也好跟git的分支代码进行一一对应。若后续以git为准则不需要额外再考虑这些。git足够灵活,可以随时捡出符合条件的代码提交至svn。
.gitignore文件定义要忽略的文件,比较重要的是[.svn/]将跟svn版本管理相关的内容排除出去,具体其他配置如下:
1 | Myconfigurations: |
svn上将项目根目录下的[.git]文件夹添加到svn:ignore即可排除