Subversion
Subversion |
外文名: Subversion 类 型: 自由开放 又 称: 时间机器 简 称: SVN 描 述: 软件项目版本控制管理系统 |
Subversion是一个自由开源的版本控制系统。在Subversion管理下,文件和目录可以超越时空。Subversion将文件存放在中心版本库里,这个版本库很像一个普通的文件服务器,不同的是,它可以记录每一次文件和目录的修改情况,这样就可以借此将数据恢复到以前的版本,并可以查看数据的更改细节。正因为如此,许多人将版本控制系统当作一种神奇的“时间机器”。[1]
目录
简介
Subversion(简称SVN)是近年来崛起的版本管理软件系统,是CVS的接班人。目前,绝大多数开源软件都使用SVN作为代码版本管理软件。 Subversion是一个版本控制系统,相对于的RCS、CVS,采用了分支管理系统,它的设计目标就是取代CVS。互联网上免费的版本控制服务多基于Subversion。 Subversion的版本库可以通过网络访问,从而使用户可以在不同的电脑上进行操作。从某种程度上来说,允许用户在各自的空间里修改和管理同一组数据可以促进团队协作。因为修改不再是单线进行(单线进行也就是必须一个一个进行),开发进度会进展迅速。此外,由于所有的工作都已版本化,也就不必担心由于错误的更改而影响软件质量—如果出现不正确的更改,只要撤销那一次更改操作即可。某些版本控制系统本身也是软件配置管理系统(SCM),这种系统经过精巧的设计,专门用来管理源代码树,并且具备许多与软件开发有关的特性——比如对编程语言的支持或者提供程序构建工具。不过Subversion并不是这样的系统,它是一个通用系统,可以管理任何类型的文件集。
历史
早在2000年,CollabNet就开始寻找CVS替代产品的开发人员。CollabNet提供了一个名为CollabNet企业版(CEE)的协作软件套件。这个软件套件的一个组成部分就是版本控制系统。尽管CEE在最初采用了CVS作为其版本控制系统,但是CVS的局限性从一开始就很明显,CollabNet知道迟早要找到一个更好的替代品。遗憾的是,CVS已经成为开源世界事实上的标准,很大程度上是因为没有更好的替代品,至少是没有可以自由使用的替代品,所以CollabNet决定从头编写一个新的版本控制系统,这个系统保留CVS的基本思想,但是要修正其中错误和不合理的特性。 2000年2月,他们联系到OpenSource Development with CVS(Coriolis,1999)的作者Karl Fogel,并且询问他是否希望为这个新项目工作。巧合的是,当时Karl正在与朋友Jim Blandy讨论设计一个新的版本控制系统,1995年时,他们两人曾经开办了一个提供CVS支持的公司CyclicSoftware,尽管他们最终卖掉了公司,但还是天天使用CVS进行日常工作。使用CVS时的挫折促使Jim认真的思考如何管理版本化的数据,并且他当时不仅使用了“Subversion”这个名字,并且已经完成了Subversion版本库的最初设计,所以当CollabNet提出邀请的时候,Karl马上同意为这个项目工作,同时Jim也找到了他的雇主(RedHat软件公司)允许他到这个项目工作,并且没有限定最终的期限。CollabNet雇佣了Karl和BenCollinsSussman,详细设计工作从三月开始,在Behlendorf、CollabNet、JasonRobbins和GregStein(当时是一个独立开发者,活跃在WebDAV/DeltaV系统规范制订工作中)恰到好处的激励下,Subversion很快吸引了许多活跃的开发者,结果是许多对CVS有过失望经历的人很乐于为这个项目做些事情。 最初的设计小组设定了简单的开发目标。他们不想在版本控制方法学中开垦处女地,他们只是希望修正CVS。他们决定Subversion应符合CVS的特性,并保留相同的开发模型,但不再重复CVS的一些显著缺陷。尽管Subversion并不需要成为CVS的完全替代品,但它应该与CVS保持足够的相似性,以使CVS用户可以轻松的转移到Subversion上。 经过14个月的编码,2001年8月31日,Subversion能够“自己管理自己”了,开发者停止使用CVS保存Subversion的代码,而使用Subversion本身。 虽然CollabNet启动了这个项目,并且一直提供了大量的工作支持(它为一些全职的Subversion开发者提供薪水),但Subversion像其它许多开源项目一样,被松散的、透明的规则管理着,这样的规则激励着知识界的精英们。CollabNet的版权许可完全符合Debian的自由软件方针。也就是说,任何人都可以根据自己的意愿自由的下载、修改和重新发布Subversion,不需要CollabNet或其他人的授权。
功能
·包含绝大部分CVS的功能 CVS是最基本的版本控制系统。Subversion包含了CVS的大部分功能,并且针对有些功能还稍加改进。 ·目录的版本化 Subversion将目录名以版本号的形式体现。 ·基于版本的复制,删除和重命名 无论复制、删除还是重命名,都会被打上版本号,尽管这听上去有些奇怪。 ·自由的版本化元数据操作 Subversion允许任何元数据附加在文件或目录中。这些属性是键/值对,并且被版本化。Subversion也提供对修订版附加任何键/值属性的方法,这些属性不会被版本化,因为他们会自动将元数据附加到版本空间中,但他们可以随时被更改。 ·混合追踪 Subversion 1.5开始加入了混合追踪功能。 ·文件锁 支持文件锁定,当多个用户试图编辑同一个文件时会收到警告。 ·Apache网络服务的支持,基于WebDAV/DeltaV协议 使用基于HTTP的WebDAV/DeltaV协议进行网络通信,而Apache网络服务器提供网络存储的站点服务。 ·可执行的标签 当一个文件是可执行的时候,Subversion会提示,并且当这个可执行的文件被放在版本控制中时,Subversion会防止该程序检查其他目录。 ·独立进程模式 Subversion可以运行在独立模式下 ·一个只读的存储镜像 Subversion提供一个工具,SVNsync, 用于同步主服务器上的 文件到一个子存储服务器上,并且标为只读的属性
使用情况
虽然在 2006年 时 Subversion 的使用族群仍然远少于传统的 CVS,但已经有许多开放源码团体决定将 CVS 转换为 Subversion。已经转换使用 Subversion 的包括了 FreeBSD、Apache Software Foundation、KDE、GNOME、GCC、Python、Samba、Mono 以及许多团体。许多开发团队换用 Subversion 是因为 Trac、SourceForge、CollabNet、CodeBeamer等专案协同作业软件以及Eclipse、NetBeans等IDE提供 Subversion的资源整合。 除此之外,一些自由软件开发的协作网如SourceForge.net除了提供 CVS 外,现在也提供专案开发者使用 Subversion 作为源码管理系统, JavaForge、Google Code以及 BountySource则以 Subversion 作为官方的源码管理系统。 2009年,绝大多数CVS服务已经改用SVN。CVS已经停止维护。
客户端
Subversion的客户端有两类,一类是WebSVN等基于Web的,一种是以TortoiseSVN为代表的客户端软件。前者需要Web服务器的支持,后者需要用户在本地安装客户端,两种都有免费开源软件供使用。
服务器
Subversion支持Linux和Windows,更多是安装在Linux下。 SVN服务器有2种运行方式:独立服务器和借助Apache。2种方式各有利弊。 SVN存储版本数据也有2种方式:Berkeley DB和FSFS。因为Berkeley DB方式在服务器中断时,有可能锁住数据,所以还是FSFS方式更安全一点。
优点
在SVN之前,CVS(Concurrent Version System:协同版本控制系统)是使用最广泛的版本管理软件,服务器上保存所有的开发项目,开发者们通过服务器上的共享目录,共同开发同一个项目,达到追踪所有的工作进度,而服务器上也会保存历史版本信息,以方便开发者排错。 SVN与CVS对比的优点如下:
- 统一的版本号。CVS是对每个文件顺序编排版本号,在某一时间各文件的版
本号各不相同。而Subversion下,任何一次提交都会对所有文件增加到同一个新版本号,即使是提交并不涉及的文件。所以,各文件在某任意时间的版本号是相同的。版本号相同的文件构成软件的一个版本。
- 原子提交。一次提交不管是单个还是多个文件,都是作为一个整体提交的。在这当中发生的意外例如传输中断,不会引起数据库的不完整和数据损坏。
- 重命名、复制、删除文件等动作都保存在版本历史记录当中。
- 对于二进制文件,使用了节省空间的保存方法(简单的理解,就是只保存和上一版本不同之处)。
- 目录也有版本历史。整个目录树可以被移动或者复制,操作很简单,而且能够保留全部版本记录。
- 分支的开销非常小。
- 优化过的数据库访问,使得一些操作不必访问数据库就可以做到,这样减少了很多不必要的和数据库主机之间的网络流量。
不足
只能设置目录的访问权限,无法设置单个文件的访问权限。 若用户有设置单个文件的访问权限的需求,国内有单位可提供基于开源Subversion的扩展版本,见参考资料。 另外,Subversion的官方版本不支持NTFS文件系统的扩展属性,NTFS的扩充属性(安全属性、附加数据流(可选数据流)、加密数据流等)在提交、检出、导入、导出等操作过程中会丢失。 现在国内有提供支持NTFS扩展属性的扩充版Subversion、tSVN, 即NTFS的扩充属性(安全属性、附加数据流(可选数据流)、加密数据流等)可和文件一起被提交、检出、导入、导出。见参考资料。
企业级
Subversion Multisite 对于企业级应用,Subversion还有其先天不足,比如对于多个地点的并行开发。目前Subversion multisite,实现异地对等服务器自动同步,支持并行开发以及异地备份。 基于Subversion的ALM平台——UberSVN ALM(Application Lifecycle Management)是软件配置管理的未来趋势,各种软件版本工具包括Subversion都要集成到其中。目前UberSVN是唯一的以Subversion为基础构建的ALM平台,并实现了协同开发以及社交化编码。 是客户端还是服务器 Subversion代表的是代码版本管理的一种标准,没有严格区分其到底是服务器还是客户端,同样提供二者的功能。
特性
Subversion支持: 版本化的目录 CVS只能跟踪单个文件的变更历史,但是Subversion实现的“虚拟”版本化文件系统则可以跟踪目录树的变更。在Subversion中,文件和目录都是版本化的。 真实的版本历史 由于只能跟踪单个文件的变更,CVS无法支持如文件拷贝和改名这些常见的操作——这些操作改变了目录的内容。同样,在CVS中,一个目录下的文件只要名字相同即拥有相同的历史,即使这些同名文件在历史上毫无关系。而在Subversion中,可以对文件或目录进行增加、拷贝和改名操作,也解决了同名而无关的文件之间的历史联系问题。 原子提交 一系列相关的更改,要么全部提交到版本库,要么一个也不提交。这样用户就可以将相关的更改组成一个逻辑整体,防止出现只有部分修改提交到版本库的情况。 版本化的元数据 每一个文件和目录都有自己的一组属性——键和值,可以根据需要建立并存储任何键/值对。与文件本身的内容一样,属性也在版本控制之下。 可选的网络层 Subversion在版本库访问的实现上具有较高的抽象程度,利于人们实现新的网络访问机制。Subversion可以作为一个扩展模块嵌入到Apache之中,这种方式在稳定性和交互性方面有很大的优势,可以直接使用服务器的成熟技术——认证、授权和传输压缩等。此外,Subversion自身也实现了一个轻型的、可独立运行的服务器软件,这个服务器使用了一个自定义协议,可以轻松地使用SSH封装。 一致的数据操作 Subversion用一个二进制差异算法描述文件的变化,对于文本(可读)和二进制(不可读)文件其操作方式是一致的,两种类型的文件压缩存储在版本库中,而差异信息则在网络上双向传递。 高效的分支和标签操作 在Subversion中,分支与标签操作的开销与工程的大小无关。Subversion的分支和标签操作只是一种类似于硬链接的机制拷贝整个工程,因而这些操作通常只会花费很少且相对固定的时间。 可修改性 Subversion没有历史负担,它以一系列优质的共享C程序库的方式实现,具有定义良好的API,这使得Subversion非常容易维护,和其它语言的互操作性很强。
架构
Subversion设计总体上的“俯视图”。图中的一端是保存所有版本数据的Subversion版本库,另一端是Subvesion的客户程序,管理着所有版本数据的本地映射(称为“工作拷贝”),在这两极之间是各种各样的版本库访问(RA)层,某些使用电脑网络通过网络服务器访问版本库,某些则绕过网络服务器直接访问版本库。
组件
安装好的Subversion由几个部分组成,下面将简单的介绍一下这些组件。下文的描述或许过于简略,不易理解,但不用担心,本书后面的章节中会用更多的内容来详细阐述这些组件。 SVN 命令行客户端程序。 SVNversion 此工具用来显示工作拷贝的状态(用术语来说,就是当前项目的修订版本)。 SVNlook 直接查看Subversion版本库的工具。 SVNadmin 建立、调整和修复Subversion版本库的工具。 SVNdumpfilter 过滤Subversion版本库转储数据流的工具。 mod_dav_SVN ApacheHTTP服务器的一个插件,使版本库可以通过网络访问。 SVNserve 一个单独运行的服务器程序,可以作为守护进程或由SSH调用,这是另一种使版本库,可以通过网络访问的方式。 SVNsync 一个通过网络增加镜像版本库的程序。
基本概念
先为那些不熟悉版本控制技术的入门者提供一个简单扼要、非系统的介绍,这里将从版本控制的基本概念开始,随后阐述Subversion的独特理念,并演示一些使用Subversion的例子。 下面以分享程序源代码作为例子,但是记住Subversion可以管理任何类型的文件集——它并非是程序员专用的。
版本库
一个典型的客户/服务器系统 Subversion是一个“集中式”的信息共享系统。版本库是Subversion的核心部分,是数据的中央仓库。版本库以典型的文件和目录结构形式的文件系统树来保存信息。任意数量的客户端连接到Subversion版本库,读取、修改这些文件。客户端通过写数据将信息分享给其他人,通过读取数据获取别人共享的信息。图“一个典型的客户/服务器系统”展示了这种系统: Subversion听起来跟一般的文件服务器没什么不同。事实上,Subversion的版本库的确是一种文件服务器,但不是“一般”的文件服务器。Subversion版本库的特别之处在于,它会记录每一次改变:每个文件的改变,甚至是目录树本身的改变,例如文件和目录的添加、删除和重新组织。 一般情况下,客户端从版本库中获取的数据是文件系统树中的最新数据,但是客户端也具备查看文件系统树以前任何一个状态的能力。举个例子,客户端有时会对一些历史性问题感兴趣,比如“上星期三时的目录结构是什么样的?”或者“谁最后一个修改了这个文件,都修改了什么?”这些都是版本控制系统的核心问题(设计用来记录和跟踪数据变化的系统)。
版本模型
版本控制系统的核心任务是实现协作编辑和数据共享。但是不同的系统使用不同的策略实现这个目的。有理由去理解这些策略的区别,首先,如果遇到了其他类似Subversion的系统,可以帮助比较现有的版本控制系统;此外,可以帮助更有效的使用Subversion,因为Subversion本身支持不同的工作方式。
文件共享
所有的版本控制系统都需要解决这样一个基础问题:怎样让系统允许用户共享信息,而不会让他们因意外而互相干扰?在版本库里意外覆盖别人的更改非常容易。
注意事项
考虑“需要避免的问题”的情景,有两个共同工作者,Harry和Sally,他们想同时编辑版本库里的同一个文件,如果首先Harry保存它的修改,过了一会,Sally可能凑巧用自己的版本覆盖了这些文件,Harry的更改不会永远消失(因为系统记录了每次修改),但Harry所有的修改不会出现在Sally新版本的文件中,所以Harry的工作还是丢失了,至少是从最新的版本中丢失了,而且可能是意外的,这是要明确避免的情况! 锁定-修改-解锁方案 许多版本控制系统使用锁定-修改-解锁机制解决这种问题,在这样的模型里,在一个时间段里版本库的一个文件只允许被一个人修改。首先在修改之前,Harry要“锁定” 住这个文件,锁定很像是从图书馆借一本书,如果Harry锁住这个文件,Sally不能做任何修改,如果Sally想请求得到一个锁,版本库会拒绝这个请求。在Harry结束编辑并且放开这个锁之前,她只可以阅读文件。Harry解锁后,就要换班了,Sally得到自己的轮换位置,锁定并且开始编辑这个文件。图1.3“锁定-修改-解锁方案”描述了这样的解决方案。 锁定-修改-解锁模型有一点问题就是限制太多,经常会成为用户的障碍: 1.锁定可能导致管理问题。有时候Harry会锁住文件然后忘了此事,这就是说Sally一直等待解锁来编辑这些文件,她在这里僵住了。然后Harry去旅行了,现在Sally只好去找管理员放开锁,这种情况会导致不必要的耽搁和时间浪费。 2.锁定可能导致不必要的线性化开发。如果Harry编辑一个文件的开始,Sally想编辑同一个文件的结尾,这种修改不会冲突,设想修改可以正确的合并到一起,他们可以轻松的并行工作而没有太多的坏处,没有必要让他们轮流工作。 3.锁定可能导致错误的安全状态。假设Harry锁定和编辑一个文件A,同时Sally锁定并编辑文件B,如果A和B互相依赖,这种变化是必须同时作的,这样A和B不能正确的工作了,锁定机制对防止此类问题将无能为力—从而产生了一种处于安全状态的假相。很容易想象Harry和Sally都以为自己锁住了文件,而且从一个安全,孤立的情况开始工作,因而没有尽早发现他们不匹配的修改。锁定经常成为真正交流的替代品 拷贝-修改-合并方案 Subversion、CVS和一些版本控制系统使用拷贝-修改-合并模型,在这种模型里,每一个客户联系项目版本库建立一个个人工作拷贝—版本库中文件和目录的本地映射。用户并行工作,修改各自的工作拷贝,最终,各个私有的拷贝合并在一起,成为最终的版本,这种系统通常可以辅助合并操作,但是最终要靠人工去确定正误。 下面是一个例子,Harry和Sally为同一个项目各自建立了一个工作拷贝,工作是并行的,修改了同一个文件A,Sally首先保存修改到版本库,当Harry想去提交修改的时候,版本库提示文件A已经过期,换句话说,A在他上次更新之后已经更改了,所以当他通过客户端请求合并版本库和他的工作拷贝之后,碰巧Sally的修改和他的不冲突,所以一旦他把所有的修改集成到一起,他可以将工作拷贝保存到版本库。 但是如果Sally和Harry的修改交叠了怎么办?这种情况叫做冲突,这通常不是个大问题,当Harry告诉他的客户端去合并版本库的最新修改到自己的工作拷贝时,他的文件A就会处于冲突状态,他可以看到一对冲突的修改集,并手工的选择保留一组修改。需要注意的是软件不能自动的解决冲突,只有人可以理解并作出智能的选择,一旦Harry手工地解决了冲突——也许需要与Sally讨论,它可以安全地把合并的文件保存到版本库。 拷贝-修改-合并模型感觉有一点混乱,但在实践中,通常运行的很平稳,用户可以并行的工作,不必等待别人,当工作在同一个文件上时,也很少会有交叠发生,冲突并不频繁,处理冲突的时间远比等待解锁花费的时间少。 最后,一切都要归结到一条重要的因素:用户交流。当用户交流贫乏,语法和语义的冲突就会增加,没有系统可以强制用户进行完美的交流,没有系统可以检测语义上的冲突,所以没有任何证据能够承诺锁定系统就可以防止冲突,实践中,锁定除了约束了生产力,并没有做什么事。 什么时候锁定是必需的 锁定-修改-解锁模型被认为不利于协作,但有时候锁定会更好。 拷贝-修改-合并模型假定文件是可以根据上下文合并的,就是版本库的文件主要是以行为基础的文本文件(例如程序源代码)。但对于二进制格式,例如艺术品或声音,在这种情况下,十分有必要让用户轮流修改文件,如果没有线性的访问,有些人的许多工作就最终要被放弃。 尽管Subversion一直主要是一个拷贝-修改-合并系统,但是它也意识到了需要锁定一些文件,并且提供这种锁定机制,这个特性的讨论可以见“锁定”一节。
实例研究
MartinFowler使用SVN 一两年前,我工作生涯的一个重要方面发生了变化,那之前我一直只在一台电脑上工作(更确切地说是只用一块硬盘),所有工作文件都保存在我的笔记本硬盘里。如果我要用另外一台桌面电脑,就通过文件共享操作那些文件。 自从去年我买了PowerBook事情就变了,现在我经常转战于三台机器:MacPowerBook、Windows笔记本、Ubuntu桌面。这就意味着我得保持多台机器上的东西都是最新的——至少我的工作文件都要保持最新。有了多台桌面电脑,我主要的Email服务从POP转到了IMAP,这给我带来巨大的便利——尽管它有时“打打隔”,但我敢说IMAP在我的多台机器上跑得很好(我用Thunderbird做客户端)。 我大部分工作文件都被Subversion管理起来了,每当切换机器时我就提交(commit)工作目录,再到新机器上更新(update)。一切都同步得好好的,还全面享受了版本管理服务。 不过,也有一些东西同步起来没我想要的那么方便。地址簿就很难直接同步,Thunderbird总固执地把它们放到一个特定的地方,Subversion检查不到。更倒霉的是,地址簿是二进制文件,难以合并(merge),这很烦人,但Thunderbird用文本文件来处理Email,这一点儿挺招人喜欢的,当IMAP打嗝时我也不难处理。另外,与PDA同步也很难缠,最后我还是找到个不赖的办法把所有联系人和日程表信息在三台机器上都同步好了。再者就是news聚合工具,它们之间可以通过OPML共享feeds(至少理论上如此),但不能记录下哪些我读过了哪些还没读。 文件尽量采用文本格式,这样做好处很多。我所有写作都是用XML,要同步写的东西只需要一个文本编辑器。但图表就成问题了,我还没找到一个在所有平台上都能用的东西,不过,搭起多台桌面有一个好处,所有专用于一个系统的软件我也能用了。
版本发布
2012年02月21日,Subversion Access control 4.1 引入更为敏捷灵活的授权方式。 2012年03月09日,Apache Subversion 1.7.4 发布。 2012年05月19日,Apache Subversion 1.7.5 发布。 2012年08月16日,Apache Subversion 1.7.6 发布。 2012年10月09日,Apache Subversion 1.7.7 发布。