【项目】从菜鸟向CTO晋级之路-svn和git该如何选择

    今年2月份的时候,公司启动的一个新的项目,项目启动初期考虑使用版本管理工具,眼前有svn和git两个工具可以选择。网友说:在阿里,使用git做版本管理的是项目,需求级的使用SVN,原因是因为项目有相对稳定的交付周期,代码不会有不同人员的交叉修改,所以使用git就足够,需求级则面临不同人员频繁修改同一文件的问题,那么使用svn更好。目前公司还有其他的项目在运行和维护着,一起的项目用的是svn进行版本管理的,相关的文档是使用Teambition 进行管理的,考虑现在公司项目版本历史问题和技术部同事对版本管理工具的熟悉程度,最终选择使用svn进行代码版本管理。虽然选择了svn进行代码版本管理,但是也需要弄明白svn和git的区别,并且使用场景。

一.版本控制

    什么是版本控制?版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。举个栗子,小时候特别爱玩游戏,每次玩游戏打boss之前需要存档,这个就是最原始版本管理的目的。

在网上找到的一张版本管理时代变迁图 :

【项目】从菜鸟向CTO晋级之路-svn和git该如何选择_第1张图片

这张图上分成了四个时期:

  • 史前时期:1982年的RCS。现在你可能还能在Unix的发布包中找到它。
  • 古典时期:1990年的CVS,1985年的PVCS,1992年的clearcase(价格贵,功能复杂,当然,今天还有人在用),微软的VSS(Welcome to Hell),90年代中期的Perforce(P4,这个工具今天都还在被广泛地使用,尤其是那些中等大小却有着大量开发团队的公司,现在是Google内部最大的代码管理器)。
  • 中世纪时期:SVN,AccuRev(强力支持branch和merge,其扮演了一个很重要角色帮助社区脱离clearcase和CVS),
  • 文艺复兴时期:BitKeeper——Sun的内部管理工具,Linux的内核代码2002年也用这个工具,其实,很多开源工程都在用这个工具,2005年这个工具的东家BitMover对大家对BitKeeper逆向工程很不满,于是停止支持开源,于是出现了Git。

    从图中可以看出,svn诞生于2000年,到现在也有17年的历史了,而git出来相对较晚,在2005年后诞生的,Git 诞生于一个极富纷争大举创新的年代。可以看到同期出现了其他不少创新的版本管理系统:Mercurial (Hg)、Darcs (Darcs AdvancedRevision Control System)、Bazaar (bzr)、Plastic、Team Foundation Server (TFS),其中TFS是微软的新一代scm工具。


二.svn 简介

    SVN(集中式版本控制系统)是Subversion的简称,是一个开放源代码的版本控制系统,支持大多数常见的操作系统。作为一个开源的版本控制系统,Subversion管理着随时间改变的数据。这些数据放置在一个中央资料档案库(repository)中。这个档案库很像一个普通的文件服务器,不过它会记住每一次文件的变动。这样你就可以把档案恢复到旧的版本,或是浏览文件的变动历史。Subversion是一个通用的系统,可用来管理任何类型的文件,其中包括了程序源码。


三.git简介

    自2005年诞生于以来,Git日臻成熟完善,在高度易用的同时,仍然保留着初期设定的目标。它的速度飞快,极其适合管理大项目,它还有着令人难以置信的非线性分支管理系统,可以应付各种复杂的项目开发需求。

Git(分布式版本控制系统)是一个免费的、开源分布式版本控制系统,旨在以高效和高效的方式处理从小到大的项目。Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。Git易于学习,具有闪电般的性能,占地面积小。它支持SCO工具,如Subversion,CVS,Perforce和ClearCase,具有便宜的本地分支,方便的分段区域和多个工作流等功能。


四.工作流程

SVN采用的是集中式版本控制

    这种做法带来了许多好处,特别是相较于老式的本地VCS来说。现在,每个人都可以一定程度上看到项目中的其他人正在做些什么。而管理员也可以轻松掌控每个开发者的权限。


    事分两面,有好有坏。这么做最显而易见的缺点是中央服务器的单点故障。若是宕机一小时,那么在这一小时内,谁都无法提交更新、还原、对比等,也就无法协同工作。如果中央服务器的磁盘发生故障,并且没做过备份或者备份得不够及时的话,还会有丢失数据的风险。最坏的情况是彻底丢失整个项目的所有历史更改记录,被客户端提取出来的某些快照数据除外,但这样的话依然是个问题,你不能保证所有的数据都已经有人提取出来。

集中式管理的工作流程如下图:

【项目】从菜鸟向CTO晋级之路-svn和git该如何选择_第2张图片

    集中式代码管理的核心是服务器,所有开发者在开始新一天的工作之前必须从服务器获取代码,然后开发,最后解决冲突,提交。Subversion原理上只关心文件内容的具体差异。每次记录有哪些文件作了更新,以及都更新了哪些行的什么内容。 所有的版本信息都放在服务器上。如果脱离了服务器,开发者基本上可以说是无法工作的。下面举例说明:

开始新一天的工作:

1、从服务器下载项目组最新代码。

2、进入自己的分支,进行工作,每隔一个小时向服务器自己的分支提交一次代码(很多人都有这个习惯。因为有时候自己对代码改来改去,最后又想还原到前一个小时的版本,或者看看前一个小时自己修改了哪些代码,就需要这样做了)。

3、下班时间快到了,把自己的分支合并到服务器主分支上,一天的工作完成,并反映给服务器。

 

Git采用分布式的版本控制

    在技术层面上并不存在一个像中心仓库这样的东西 , 所有的数据都在本地,不存在谁是中心,大家每个人本地都一样,但我们仍然需要协作。    


    Git记录版本历史只关心文件数据的整体是否发生变化。Git并不保存文件内容前后变化的差异数据。实际上,Git更像是把变化的文件作快照后,记录在一个微型的文件系统中。每次提交更新时,它会纵览一遍所有文件的指纹信息并对文件作一快照,然后保存一个指向这次快照的索引。为提高性能,若文件没有变化,Git不会再次保存,而只对上次保存的快照作一连接。


git的分布式版本控制的工作流程如下。

 【项目】从菜鸟向CTO晋级之路-svn和git该如何选择_第3张图片

Git的功能特性:

    1.Git中每个克隆(clone)的版本库都是平等的。你可以从任何一个版本库的克隆来创建属于你自己的版本库,同时你的版本库也可以作为源提供给他人,只要你愿意。

    2.Git的每一次提取操作,实际上都是一次对代码仓库的完整备份。提交完全在本地完成,无须别人给你授权,你的版本库你作主,并且提交总是会成功。

    3.甚至基于旧版本的改动也可以成功提交,提交会基于旧的版本创建一个新的分支。

    4.Git的提交不会被打断,直到你的工作完全满意了,PUSH给他人或者他人PULL你的版本库,合并会发生在PULL和PUSH过程中,不能自动解决的冲突会提示您手工完成。

    5.冲突解决不再像是SVN一样的提交竞赛,而是在需要的时候才进行合并和冲突解决。

 总之,公司的开发团队在进行的项目开发管理时,svn是更好的选择,团队成员共同维护公司的中心版本。


五.svn和git的区别

(1)去中心却集中

    在前面的介绍过svn和git的两种不同工作流程。每个开发者拉取(pull)并推送(push)到origin。但除了这种集中式的推送拉取关系,每个开发者也可能会从其他的开发者处拉取代码的变更,从而形成一个子团队。例如,当与两个或更多的开发者协同工作于一个大的新特性时,在将工作代码推送到持久的origin之前,这可能很有用。在上图中,Alice和Bob,Alice和David,以及Clair和David,分别构成了子团队。

从技术上讲,这只不过意味着Alice定义了一个名为bob的Git的remote,它指向了Bob的软件仓库。反之亦然。

(2)直接记录快照,而非差异

    Git 第二个思想也是和SVN最大的差异化,即每一个版本都是直接记录快照,而非文件的差异。 在网上找的区别图:

SVN :

【项目】从菜鸟向CTO晋级之路-svn和git该如何选择_第4张图片

Git:

【项目】从菜鸟向CTO晋级之路-svn和git该如何选择_第5张图片

    GIT 使用SHA-1算法计算数据的校验和 ,通过文件的内容或目录计算出SHA-1哈希值,作为指纹字符串,每个Version 都是一个快照。 所以Git的最小概念是仓库,SVN的最小概念是文件。


(3)不一样的分支概念

    因为不是记录文件差异,Git的分支本质是一个指向提交快照的指针,是从某个提交快照往回看的历史。

当创建/切换分支的时候,只是变换了指针指向而已,所以会发现创建分支非常的快,同样当git init 之后就会有一个默认的分支, 我们通常叫master ,但这实际上不是主干,没有所谓的主干和分支的差别, master只是命名为master的一个分支, 是我们为了版本管理的习惯叫法而已。


    SVN创建一个分支, 是的的确确的复制了一份文件,而如刚才说SVN的每一次Version 是记录了文件差异, 因此假入你commit了一个1M的文件到SVN服务器, SVN Server的存储增加了1M,当你删除了这个1M大小的文件并Commit的时候,SVNServer的存储又增加了1M。 所以,你是不会想知道像BAT这三家公司内部的SVN Server今天占用了多大存储空间的-。-

(4)三个工作区,三个文件状态

在 Git 中,存在三个工作区域:

  • 工作目录
  • 暂存区域
  • 本地仓库

同时,文件有三种状态:

  • 已提交(committed):该文件被安全地保存在了本地数据库
  • 已修改(modified):修改了某个文件,但还没有保存
  • 已暂存(staged):把已修改的文件放下下次保存的清单中

下图说明了这三个区域和文件状态的差别:

【项目】从菜鸟向CTO晋级之路-svn和git该如何选择_第6张图片

    在Git中,你可以暂存部分文件,甚至一个文件中的部分内容,你的本地可以将版本管理玩的非常复杂和有趣。这也是为什么 SVN 用户最常疑问 Git 为什么每次都要TM的 git add 才能再commit 的原因


六.svn和git的优缺点

SVN 的优缺点

SVN对中文支持好,操作简单,使用没有难度,美工人员,产品人员,测试人员,实施人员都可轻松上手。使用界面统一,功能完善,操作方便。


Git的优缺点

对程序源代码进行差异化的版本管理,代码库占极少的空间。易于代码的分支化管理。不支持中文,图形界面支持差,使用难度大。不易推广。 

 

七.svn和git适用范围

    (1)适用对象不同。Git适用于参与开源项目的开发者。他们由于水平高,更在乎的是效率而不是易用性。SVN则不同,它适合普通的公司开发团队。使用起来更加容易。

 

    (2)使用的场合不同。Git适用于通过Internet,有多个开发角色的单个项目开发,SVN适合企业内部由项目经理统一协调的多个并行项目的开发。

 

    (3)权限管理策略不同。Git没有严格的权限管理控制,只要有帐号,就可以导出、导入代码,甚至执行回退操作。SVN则有严格的权限管理,可以按组、按个人进行针对某个子目录的权限控制。区分读、写权限。更严格的,不支持回退操作。保证代码永远可以追踪。

 

    (4)分支(branch)的使用范围不一样。Git中,你只能针对整个仓库作branch,而且一旦删除,便无法恢复。而SVN中,branch可以针对任何子目录,它本质上是一个拷贝操作。所以,可以建立非常多、层次性的branch,并且,在不需要时将其删除,而以后需要时只要checkout老的SVN版本就可以了。

 

    (5)基于第三点,Git适用于单纯的软件项目,典型的就是一些开源项目,比如Linux内核、busybox等。相反,SVN擅长多项目管理。比如,你可以在一个SVN仓库中存放一个手机项目的bsp/设计文档/文件系统/应用程序/自动化编译脚本,或者在一个SVN中存放5款手机项目的文件系统。git中必须建立n(项目数)*m(组件数)个仓库。SVN中只需要最多n或者m个就可以了。

 

    (6)Git使用128位ID作为版本号,而且checkout时要注明是哪个branch,而SVN使用一个递增的序列号作为全局唯一的版本号,更加简明易懂。虽然可以使用gittag来建立一些文字化的别名,但是毕竟那只是针对特殊版本。

 

    (7)可跟踪性,git的典型开发过程为:建立分支,进行开发,提交到本地master,删除分支。这样做的后果是以前的修改细节会丢失。而在SVN下做同样的事情,不会丢失任何细节。这里是一个有趣的链接,表明了git下典型的工作方式:(以master为核心,不断创建新branch,删除旧branch):

 

    (8)局部更新,局部还原。SVN由于是在每个文件夹建立一个.svn文件夹来实现管理,所以可以很简单实现局部更新或者还原。假如你只希望更新某些部分,则svn可以很好实现。同时代码写错了,同时可以很好实现局部还原,当然git也可以通过历史版本还原,但是无法简单地实现局部还原。

 

    在选择项目版本管理工具的时候,也不要一味的崇拜git,还得根据公司的情况、项目情况、开发人员情况选择合适的版本工具,从而提高工作效率。希望这篇分析文能够帮助到你

你可能感兴趣的:(java)