前端版本管理
前面的话
版本管理在产品级开发中是非常重要的一个部分,它涉及到团队协作,且影响到产品最终的发布、上线以及测试环节。本文将详细介绍版本管理
概述
版本控制系统(Version Control System)是一种记录若干文件修订记录的系统,它有以下三个作用:
1、从当前版本回退到任意版本
![](https://images2015.cnblogs.com/blog/740839/201703/740839-20170331113922367-452148800.png)
2、查看历史版本
![](https://images2015.cnblogs.com/blog/740839/201703/740839-20170331113931383-718864260.png)
3、对比两个版本差异
![](https://images2015.cnblogs.com/blog/740839/201703/740839-20170331113938211-628606413.png)
分类
一般地,有四种版本控制系统。包括手动版本控制(又叫人肉VCS)、LVCS 本地、CVCS 集中式(如SVN)和DVCS 分布式(如Git)
【人肉VCS】
![](https://images2015.cnblogs.com/blog/740839/201703/740839-20170331112856727-28063515.png)
使用人肉VCS无法有效找到需要版本,无法方便地查看各个版本之间的差异,可能需要两个文件放在一起来对比。最大的问题是,污染工作目录结构,导致无法集合精力维护当前正在编辑的版本
【Local VCS(本地式)】
为了解决以上问题,出现了本地式的版本控制工具,比如RCS(Reversion Control System),其利用本地版本数据库存储不断出现的文件版本
![](https://images2015.cnblogs.com/blog/740839/201703/740839-20170331113049617-1361706225.png)
这样,它可以迅速找出需求的版本和维持工作目录结构。但是,其缺点是不支持协同开发,这也让开发者不将其选做通用的版本控制工具来使用
【Center VCS(集中式)】
集中式版本管理系统包括CVS(Cocurrent Versions System)、SVN(Subversion)、Perforce等,其中最有名的就是SVN
![](https://images2015.cnblogs.com/blog/740839/201703/740839-20170331113305539-913788621.png)
集中式版本管理系统利用中央服务器来进行日常的版本控制操作,比如checkout、commit等。所有的操作都必须经过中央服务器,优点是可控性更高,但每一次操作都需要网络请求,会影响操作的流畅性,且具有致命的单点故障。一旦中央服务器发生了故障,轻则无法协同工作,重则可能会丢失历史消息
【Distributed VCS(分布式)】
分布式版本管理系统包括Git、Mercurial等,其中最有名的是Git
![](https://images2015.cnblogs.com/blog/740839/201703/740839-20170331113432477-1542682331.png)
分布式指的是每一份本地仓库都是一个完整的项目历史拷贝,即使同步的中央服务器发生了故障,也可以很容易地从本地仓库中将历史还原出来。带来的好处是,如果部分操作不需要同步到服务器,可以在本地进行相关操作,这样可以让操作更加流畅
对比
由于Git的持续火热,对于DVCS与CVCS的争论和对比越来越多了,似乎很多文章都倾向于这个观点:" Git这种DVCS要比SVN这些DVCS要优越",实际情况真的是这样吗?
【CVCS(svn为例)】
优点:
1、 管理方便,逻辑明确,符合一般人思维习惯
2、 集中式服务器更能保证安全性,权限机制的设计也更加简洁明确。一般集中式管理的有非常明确的权限管理机制(例如分支访问限制),可以实现分层管理
3、 代码一致性非常高
缺点:
1、 中心代码服务器压力大,代码数据库容量暴增
2、 单点故障问题。如果中心服务器出现故障,所有操作都无法进行
3、 操作依赖网络。如果不能连接到代码服务器上,就不能提交,还原,对比等等,基本上不可以工作
4、 不适合开源开发(开发人数非常非常多)
【DVCS(git为例)】
优点:
1、 快速、灵活。每个开发中本地都有全量仓库,提交到本地非常快
2、 离线工作,能避免单点故障。即便远端代码服务器崩溃,开发者也能继续工作,无需等待修复。一定程度也是一种安全备份
3、 任意两个开发者之间可以很容易的合并和解决冲突
缺点:
1、 学习曲线稍微陡峭一些,要多花一点学习时间
2、 代码保密性差,不便于权限控制。一旦开发者把整个库克隆下来就可以完全公开所有代码和版本信息,权限控制需要另外一套系统来保证
因此,cvcs适合开发人数不多、对权限安全性要求更高的企业级项目;而dvcs适合团队分布在天南海北,对灵活性要求更高的开源项目
分支模型
如果多人并行在一条线上开发会导致开发困难并且难以定位错误位置
![](https://images2015.cnblogs.com/blog/740839/201703/740839-20170331114810399-2098789437.gif)
于是,分支模型出现了
分支,就是从目标仓库获得一份项目拷贝,每条分支都具有和原仓库功能一样的开发线。可以在这个开发线提交代码,也可以回退到某个版本
分支模型(Branching Model)或称之为工作流(Workflow),它是一个围绕项目开发、部署、测试等工作流的分支操作(创建及合并等)的规范集合
在小型项目中,使用下图所示的简单的分支模型已经足够
![](https://images2015.cnblogs.com/blog/740839/201703/740839-20170331125414711-1290879000.png)
在产品级的开发中,简单的分支模型不足以维护代码,接下来介绍产品级的分支模型
产品级分支模型有两类,包括常驻分支和活动分支。常驻分支一旦被创建就不会被更改;活动分支会随着产品的发布而被动态地创建,有时完成开发时会将其删除,只留下对应的版本号
【常驻分支】
开发分支(development)必须从master分支创建,而master分支就是所说的产品分支(production)
产品分支(master)上的代码都必须是可发布的,产品分支(master)也是默认分支。开发分支(development)和产品分支(master)一旦生成就不会改变
【活动分支】
特性分支(feature)是从开发分支(development)进行创建的,它是开发人员平时会经常用到的分支
Bug修复分支(hotfix)从产品分支(master)创建,因为一般都是由于线上的Bug产生的,用于修复Bug
发布分支(release)从开发分支(development)创建,它标志着一个产品开始正式发布
工作流
工作流包括特性开发和发布线两部分
【特性开发】
![](https://images2015.cnblogs.com/blog/740839/201703/740839-20170331131922524-1356095974.png)
首先从开发分支(development)创建两个特性分支(feature),这两个特性分支(feature)并行开发,feature1开发完毕后,合并到开发分支(development)上。假如feature2依赖于feature1的提交,需要将feature1的提交合并到feature2。这其中可能会有冲突,需要解决冲突。feature2开发完毕后,合并到开发分支(development)上。所有特性开发完毕,准备合并到发布分支(release)
假设,同时在开发另外一个特性分支unrelease,但该特性不在下一个版本进行发布,那么将完全不受到发布线的影响
【发布线】
![](https://images2015.cnblogs.com/blog/740839/201703/740839-20170331130813711-2062851465.png)
当所有的特性分支(feature)都合并到开发分支(development),准备发布,创建发布分支(release),它会拥有当前开发分支(development)的所有信息
之后,进行一些产品的Bug修复,也会有一些源数据(如版本号、配置文件等)的更新,所有的这些在发布分支(release)提交的代码都需要合并到开发分支(development),这样更好地在开发分支(development)进行版本的维护。因为,发布分支(release)是一个活动性分布,它可能会在发布结束之后被删除
接下来,准备在发布分支(release)上发布1.0版本,然后将发布分支(release)提交的代码合并到开发分支(development)。除此之外,还需要推送到产品分支(master),并打上版本号(V1.0)。由于产品分支(master)的代码可以直接上线,所以推送到产品分支(master)意味着该版本要上线了
但有时,开发并不理想,会在线上也就是产品分支(master)上发现一些Bug,这些Bug会通过小版本进行处理。比如在(v0.1)版本发现一个Bug,会创建一个Bug修复分支(hotfix),完成Bug修复,将其合并到产品分支(master),创建(v0.2)版本
这里要注意的一点是代码修复的提交也需要合并到开发分支(development)。这样,在后续这个热修复的分支被删除之后也能定位到该提交
环境
![](https://images2015.cnblogs.com/blog/740839/201703/740839-20170331131128492-452705771.png)
开发环境使用测试/开发配置,包括数据库、缓存、元数据配置等信息,使用的是需要提交到下一个发布分支(release)的特性分支(feature)的代码,基本上会在本地测试特性分支(feature)
测试环境使用测试配置,包括测试数据库、缓存等,使用的是发布分支(release)或开发分支(development)的代码
预发布环境,相当于一个小范围的发布,为了更好地模拟真实环境,使用线上数据库。它使用的是发布分支(release)的代码
生产环境使用线上配置,使用的是产品分支(master)的代码
最后
本文是蔡剑飞、郑海波老师的《产品前端架构》课程中《版本管理》章节的学习记录