上一篇博客大致聊了聊关于版本控制系统的周边,这一篇我们就来继续唠唠作为近年来最受欢迎的两个版本控制系统的优缺点吧。

聊优缺点之前,先简单了解一下这两个这两个版本控制系统好了:

关于 SVN

SVN 概述

SVN 毫无疑问是一个缩写,它的全称是:Subversion,名字源于创作者之一的 Ben Collins-Sussman ,中文释义:“颠覆”,意为颠覆 CVS 的版本。

SVN 是 CollabNet 于 2000 年创建的开源项目,创作初衷是为了对当时最受欢迎的版本控制系统 CVS 进行修正和补充。

在2000年2月项目创建之初他们就愉快地联系上了 CVS 的“亲妈”——Open Source Development with CVS(Coriolis, 1999)的作者 Karl Fogel,邀请他一同为这个新项目工作,而 Karl 本人也因在使用 CVS 时受到束缚而在考虑如何改进创新,故此一拍即合,欣然拉着和他有相同想法的朋友—— Ben Collins-Sussman ,一起参与了 SVN 的开发工作。

由于初衷是对 CVS 的修复与补充,故此 SVN 保留着与 CVS 相同的开发模型,使得 CVS 的用户可以不费什么力气地从 CVS 转换至 SVN 。

SVN 的工作流程

和 CVS 一样 SVN 是集中式版本控制系统,其核心在于版本库只在中央服务器上,所有想要获取、想要更改其内容的人都必须通过互联网的途径连接中央仓库。

言语太过苍白,直接上图吧:

由上图可以清晰地感受到,实际上中央版本库就是一个大型的“资源共享场地”或者说是一个“情报局”——如果把提交上去的项目看作情报或者资源的话。

举个栗子:

如果把一个放进 SVN 的公司项目比作一个"情报局",那么每一个参与这个项目的人都是可以从这个“情报局”获取情报的成员,

每一个成员获取或是更改“情报”都必须在“情报局”全方位观测的情况下——获取或更改等操作必须全程联网。

不同的成员能获取到的“情报内容”有所不同——因为 SVN 有权限管理,但只能根据“情报类型”——只能设置目录的访问权限,不能设置单个文件的访问权限。

如果多个成员都在更改同一则“情报”,大多数情况下都需要拼手速,要是有人先一步将自己更改过的“情报”上交,那后面的人就只会被无情地阻挡。若想继续将自己更改内容提交,只能先获取已被更改过的“情报”,再更改自己想更改的内容,进一步提交。要是此时又有人捷足先登,那只能苦逼地继续先获取再更改了。

“情报局”也为提供“情报”的成员设立单人间,成员可以将自己要更改的“情报”带进单人间进行操作,更改之后再将“情报”带出来上交,完美地解决了拼手速的问题——文件锁。

事实上,光是有“单间”是远远不够的。文件锁同样存在着很大一部分问题:比如加锁的人改完文件忘解锁了;比如虽然想改的是同一个文件,但相互之间互不干扰,本可以并行的,加了锁无法并行,降低了效率;比如因为文件锁的存在给人一种安全的错觉,所以更改的时候并没有事先商量,结果虽然改的是不同的文件,但文件间相互关联,修改的内容在语义上并不兼容,再提交……哦,那画面太美我不敢想。

所以 SVN 又提出了另一解决方案——“复制-修改-合并方案”——每一个用户的客户端都与仓库通信,在本地创建一份私有的工作副本,然后用户可以同时地互不干扰地修改自己的私有副本,最后将私有副本合并为一个新的最终版本,当然, SVN 会提供合并操作,但归根结底,必须由用户自己来确保合并的结果是正确的。

沿用上面那个例子就是:如果有多个成员对同一份“情报”有异议想更改,那么“情报局”就会让你们各自将“情报”复制一份,自己拿去修改,修改完上交“情报局”,“情报局”也会帮忙把这几份修改过的“情报”统筹之后收录为新版本,但“情报局”并不能保证它统筹过后的“情报”是否准确,需要成员们自行去确认或修正“情报”的准确性。

这个“复制-修改-合并方案”是不是很耳熟?ε=(´ο`*)))唉,人类的发展就是一个相互借鉴、相互成长的过程呐。

SVN的特点:

  1. 拥有统一的版本号。和 CVS 对每一个文件按顺序编排版本号不同,SVN 任何一次提交都会将所有文件增加到同一个新版本号,即使是该次提交不涉及到的文件,这样就使得拥有同一版本号的所有文件集体构成软件的一个版本。
  2. 原子提交。每次提交不管是单个或是多个文件,都是以文件作为一个整体提交的,如果传输过程被中断之类的,也不会引起数据库的不完整和数据损坏。
  3. 对于重命名、复制、删除文件等这些操作都会保存在版本历史记录中。
  4. 原理上只关心文件内容的具体差异。每次记录有哪些文件作了更新,以及都更新了哪些行的什么内容。只保存与上一版不同之处,极大地节约了空间。
  5. 目录也有版本历史。整个目录树可以被移动或者复制,操作很简单,而且能够保留全部版本记录。
  6. 分支的开销非常小。
  7. 优化过的数据库访问,使得一些操作不必访问数据库就可以做到。这样减少了很多不必要的和数据库主机之间的网络流量。
  8. 支持元数据(Metadata)管理。每个目录或文件都可以定义属性(Property),它是一些隐藏的键值对,用户可以自定义属性内容,而且属性和文件内容一样在版本控制范围内。
  9. 文件锁。支持文件锁定。如果一个人想更改文件,那他可以在修改之前对文件进行“加锁”,如果他已经锁住了文件,别人就不能再对同一文件进行加锁,也不能修改文件,只能等他完成修改然后释放锁,等他解锁之后,其他人才能对该文件新版本进行上锁编辑。
  10. 支持 FSFS 和Berkeley DB两种资料库格式
  11. 集中式版本控制,方便管理文档。

关于Git

Git概述

创建 Git 的大神曾自嘲自己编辑的这个版本控制系统为”愚蠢的内容跟踪器“。

与 SVN 不同 Git 最初的开发动力来自于 BitKeeperMonotone ,起因是 Linux 之父 Linus Torvalds 在 2002年决定启用 BitKeeper 来作为 Linux 内核的版本控制系统。虽然 BitKeeper 不是开源项目引起了社区内一些人的不满,但人家愿意为 Linux 提供免费的服务(免费的多香啊),所以还是有惊无险地度过了两三年时光;直到 Linux 社区中有人试图用自己的代码自行连接 BitKeeper 的存储库,还被发现了……

道歉是不可能道歉的,所以 BitMover 关停了 BitKeeper 对 Linux 的免费支持,所以本来也有此意向的 Linux 之父用 C 语言开启了他为期十天的 Git 创作,然后 Git 诞生了。

Git 最初版本发布于2005年7月11号,作为 Linux 内核主要的版本控制系统,它也是一个开源项目。与 CVS 和 SVN 这类集中式版本控制系统不同,它采用分布式版本库的方法,使源代码的发布和交流及其方便。

同时,Git 本着开源自由的主义精神,并没有对版本库的浏览和修改做任何的权限限制,通过其他工具也能够达到有限的权限控制。得益于此,Git 不再局限于原来的活动范围—— Linux 和 Unix,为广大Windows用户带来了福音。

Git工作流程

git 是分布式的版本控制系统,它由公共版本库和本地版本库组成,将项目主题存放在公共版本库中,每个开发者都可以通过克隆,在本地机器上拷贝出一个完整的Git仓库。

没找着可以用的图,手残换了一张,将就看吧,大概就这个意思

公共版本库可以放在服务器上、放在网站上、放在任一本地机器上都可以。需要进行操作时,先从公共版本库中拉取最新版本到本地,然后再进行修改,如果没有网的情况下也可以先进行修改,提交到本地仓库,等有网的时候再进行拉取,推送等操作。

因为每一个本地库都有完整的git仓库,且编辑的时候都在本地进行的,所以也就不会存在需要拼手速抢着提交的问题。但是,每一推送前最好都拉取一遍,防止你在编辑的过程中有人向公共版本库推送了他自己的修改,如果对方修改的内容与你修改的内容不冲突,那么直接推送是没有问题的, Git 有相应的合并操作;要是对方修改的内容与你改的内容有冲突, Git 也提供了相应的工具(resolve)去供开发者们手动调解冲突。冲突调解完成后,就可以继续推送了。

这一步操作是不是很眼熟?是的,这就是前面借鉴的对象。

Git的特点:

  1. 得益于它分布式的特点,很多操作都可以在本地进行,致使几乎除了克隆以外的其他操作都十分地快速。
  2. 远端与本地都保存着完整的git仓库(包括代码与版本信息等),编辑过程中不需要联网,可以等有网的时候在进行推送;且每个用户基本上都有完整备份。如果发生崩溃或损坏,可以向上推每个副本以替换。
  3. 不需要服务器端软件,可以运作版本控制。使得源代码的发布和交流及其方便。
  4. 只关心文件数据的整体是否发生变化。不保存文件内容前后变化的差异数据。更像是把变化的文件作快照后,记录在一个微型的文件系统中。每次提交更新时,纵览一遍所有文件的指纹信息并对文件作一快照,然后保存一个指向这次快照的索引。为提高性能,若文件没有变化,不会再次保存,而只对上次保存的快照作一连接。
  5. 分支的本质是一个指向提交快照的指针,速度快,灵活,分支之间可以任意切换。
  6. 可以同时拥有多个完全独立的本地分支,这些分支的创建、合并和删除操作只需要几秒,分支之间的切换更是丝般顺滑,且在推送远端的时候可以选择性推送共享分支,而不是将所有的分支都推送上去。
  7. 它使用的数据模型可确保项目每个部分的加密完整性。所有的数据在存储前都计算校验和,然后以校验和来引用。 这意味着不可能在它不知情时更改任何文件内容或目录内容

SVN 与 Git 各自的优劣

前面描述他们的时候,也大致聊了聊我所了解到的他们各自的特点,这里也聊聊他们各自的优势、劣势吧。

SVN 的优势:

  1. 用法简单,易上手,没有 Git 那么多的命令,对新手比较友好。
  2. 易于管理,对权限的管理相当严格,可以按组、个人针对某个子目录的权限控制。
  3. 文档锁一定意义上真的非常有用,尤其是分工明确,且不愿意让别人碰自己代码的时候。
  4. 本地设备上的文件更小,更省内存,尤其是做大项目的时候,对电脑内存比较友好。
  5. 可以单独检出某个有权限的目录。
  6. 有全局版本号——不需要手动编号。

SVN 的劣势:

  1. 项目放在中央服务器中,一旦服务器出现什么意外,就会损失惨重。
  2. 断网意味着不能工作,比较扎心。联内网还好,联外网能卡得你怀疑人生。
  3. 人一多服务器就有点遭不住,尤其是那种大型开源项目。
  4. 分支管理不灵活,svn分支是一个完整的目录,且这个目录拥有完整的实际文件,这些操作都是在服务端进行同步的,不是本地化操作,如果要删除分支,也是需要将远程的分支进行删除,这会导致大家都得同步。

Git的优势:

  1. 速度快,灵活。
  2. 离线工作。
  3. 十分详细且忠实地反映版本间的变化,能够及时且方便地解决冲突。
  4. 拥有多个完整独立的分支,且可以只选择推送共享分支。
  5. 本地拥有完整的 git 版本库,无论损坏了那一边,都能够通过克隆的方式恢复。

Git的劣势:

  1. 权限管理形同虚设,几乎所有人都能获取更改全部文件,难保会不会有傻缺更改注释不全的代码,导致报错……而且也很容易被人扒源码挂网上。
  2. 模式上比 SVN 复杂,相对的学习周期更长。

大致就这些吧,可能还不是很详细,原本也没想到会整理那么久,头都要大了。要是还有不全的,就交给未来的自己补充吧,下面是我在整理学习的时候参看的内容。大佬们写的也都很详细,很不错,要是看完上面还不懂的话,不要犹豫,顺着网线通过链接去膜拜大佬吧。

麻烦转载引用的一定要标注来源呀。

参考资料(排名不分先后)

Subversion - 维基百科,自由的百科全书 (wikipedia.org)

git - 维基百科,自由的百科全书 (wikipedia.org)

林纳斯·托瓦兹 - 维基百科,自由的百科全书 (wikipedia.org)

subversion_百度百科 (baidu.com)

Subversion 版本控制-中文帮助文档[加锁-修改-解锁 解决方案] (red-bean.com)

关于 - git (git-scm.com)

GIT(分布式版本控制系统)_百度百科 (baidu.com)

Svn和Git的一次详细对比 - ic翼 (bingyishow.top)

Git和SVN的区别 - 慕尘 - 博客园 (cnblogs.com)

对比 Git 与 SVN,这篇讲的很易懂 - SegmentFault 思否

SVN与Git比较的优缺点差异 - Tse先生 - 博客园 (cnblogs.com)

版本控制工具 - git和svn(优缺点对比) - 程序员大本营 (pianshen.com)

最新文章

  1. C# 破解 Reflector8.5
  2. 04.ubuntu下kvm 命令行安装64位ubuntu报"Couldn't find hvm kernel for Ubuntu tree."的问题
  3. 解决:Microsoft Office Word已停止工作
  4. Android 大牛的 blog 值得推荐 (转 整理)
  5. TypeScript开发手册
  6. MIT jos 6.828 Fall 2014 训练记录(lab 2)
  7. osgi 命令
  8. java之RTTI和反射的理解
  9. 关于URL 解码, 编码
  10. .Net中把图片等文件放入DLL中,并在程序中引用
  11. Unity 发布到IOS,Android的各种坑
  12. 菜鸟VUER学习记——零0章、打开新的大门
  13. 电梯调度设计之初感想——蔡迎盈&&曹玉松
  14. 快速去水印(win10换图3D工具)
  15. JAVA 学习日记
  16. android初学
  17. 【多媒体封装格式详解】--- AAC ADTS格式分析
  18. OpenCV入门(1)- 简介
  19. mysql之event
  20. poj1573模拟

热门文章

  1. “可变的”tuple
  2. select执行顺序
  3. [Java] HOW2J(Java中级)
  4. Unix下 压缩和解压缩命令
  5. ./g1.sh q w e r 5个参数 bash命令 获取 命令实际的参数 shell文件名称$0 第一个参数$1第2个参数$2 最后一个参数$#;参数个数$#个;所有的参数列出来$* 返回值$? 正确0 失败1
  6. BUUCTF(八)[极客大挑战 2019]LoveSQL
  7. Java Stream 流(JDK 8 新特性)
  8. Centos6.9以下查看端口占用情况和开启端口命令
  9. unity 2017 卡在 loading界面
  10. 出现异常org.yaml.snakeyaml.parser.ParserException: while parsing a block mapping