本手册旨在描述 Apache™ Subversion® 1.7.x 系列。如果您正在运行其他版本的 Subversion,我们强烈建议您访问 https://svnbook.subversion.org.cn/ 并查阅适合您 Subversion 版本的文档。
Subversion 是一个免费/开源的 版本控制系统 (VCS)。也就是说,Subversion 会随着时间的推移管理文件和目录以及对它们的更改。这使您可以恢复数据的旧版本,或检查数据更改的历史记录。在这方面,许多人认为版本控制系统是一种 “时间机器。”
Subversion 可以在网络上运行,这使得它可以被不同计算机上的人使用。在某种程度上,不同的人能够从各自的位置修改和管理同一组数据的能力促进了协作。进度可以更快地进行,而无需通过单个管道进行所有修改。而且由于工作是版本化的,您不必担心质量会因为失去该管道而受到影响——如果对数据进行了一些错误的更改,只需撤消该更改即可。
一些版本控制系统也是 软件配置管理 (SCM) 系统。这些系统专门用于管理源代码树,并具有许多针对软件开发的特定功能——例如,本机理解编程语言,或提供用于构建软件的工具。但是,Subversion 不是这些系统之一。它是一个通用系统,可以用于管理 任何 文件集合。对于您来说,这些文件可能是源代码——对于其他人来说,任何东西,从杂货购物清单到数字视频混音等等。
如果您是正在考虑使用 Subversion 的用户或系统管理员,您应该问自己的第一个问题是:“这是否适合这项工作的工具?” Subversion 是一把很棒的锤子,但要小心不要把每个问题都看成钉子。
第一步,你需要决定版本控制是否适合你的需求。如果你需要存档旧版本的文件夹和文件,可能需要恢复它们,并查看它们随时间变化的日志,那么版本控制工具可以做到。如果你需要与他人协作编辑文档(通常通过网络),并追踪谁做了哪些修改,版本控制工具也可以做到。事实上,这就是为什么像 Subversion 这样的版本控制工具在软件开发环境中如此常用的原因——团队开发本质上是一种社交活动,源代码文件的修改会不断地被讨论、修改、评估,甚至有时会被撤销。版本控制工具促进了这种协作。
使用版本控制也存在成本。除非你能将版本控制系统的管理外包给第三方,否则你将承担自行管理的显而易见的成本。在日常使用数据时,你将无法像往常一样复制、移动、重命名或删除文件。相反,你必须通过版本控制系统来完成所有这些操作。
即使你已经接受了版本控制系统带来的成本效益权衡,也不应该仅仅因为它可以满足你的需求就选择使用它。考虑一下你的需求是否可以通过其他工具更好地解决。例如,由于 Subversion 将数据复制给所有参与的协作者,因此一个常见的误用是将其视为一个通用的分发系统。人们有时会使用 Subversion 来分发大量的照片、数字音乐或软件包。问题是,这种数据通常不会发生变化。集合本身会随着时间的推移而增长,但集合中的单个文件不会被修改。在这种情况下,使用 Subversion 就“杀鸡用牛刀”[2]。有一些更简单的工具可以有效地复制数据,而无需跟踪更改的开销,例如 rsync 或 unison。
一旦您决定需要一个版本控制解决方案,您会发现可用的选项并不少。当 Subversion 首次设计和发布时,版本控制的主要方法是 集中式版本控制——一个单一的远程主存储库,存储版本化数据,单个用户在本地操作,针对该数据的版本历史记录的浅层副本。Subversion 在其最初引入后迅速成为该版本控制领域的领导者,获得了广泛的采用,并取代了许多旧版本控制系统的安装。它至今仍保持着这一突出地位。
然而,自那以后发生了很多变化。在 Subversion 项目开始其生命周期的这些年里,一种称为 分布式版本控制 的更新的版本控制方法也获得了广泛的关注和采用。像 Git (https://git.js.cn/) 和 Mercurial (http://mercurial.selenic.com/) 这样的工具迅速跃居分布式版本控制系统 (DVCS) 的榜首。分布式版本控制利用高速网络连接和低存储成本的日益普及,提供了一种与集中式模型在关键方面不同的方法。首先也是最明显的是,没有远程的中央存储库来存储版本化数据。相反,每个用户都保留并操作针对非常深层的——从某种意义上说是完整的——本地版本历史数据存储。协作仍然存在,但通过直接在用户本地数据存储之间交换 变更集(对版本化项目进行的更改集合)来完成,而不是通过集中式主数据存储。事实上,任何类似于项目版本化数据的规范 “主” 源的表象都仅仅是约定俗成,由该项目的各个协作者赋予的状态。
每种版本控制方法都有其优缺点。也许 DVCS 工具带来的两个最大好处是日常操作的惊人性能(因为主要数据存储在本地)以及对分支之间合并的极大支持(因为合并算法是 DVCS 工作的核心)。缺点是分布式版本控制本质上是一个更复杂的模型,这可能会给舒适的协作带来不可忽视的挑战。此外,DVCS 工具之所以能很好地完成工作,部分原因是它们从用户那里保留了一定程度的控制权,而集中式系统则可以自由地提供这些控制权——实现基于路径的访问控制、灵活地更新或回溯单个版本化数据项等。幸运的是,许多明智的组织已经发现,这不必是一个宗教辩论,Subversion 和 Git 等 DVCS 工具可以在组织内部和谐地使用,每个工具都服务于最适合该工具的目的。
唉,这本书是关于 Subversion 的,所以我们不会尝试对 Subversion 和其他工具进行全面比较。有选择版本控制系统选项的读者被鼓励研究可用的选项,并做出最适合自己和同事的决定。如果在这样做之后,Subversion 是您选择的工具,那么在接下来的章节中,将有大量关于如何成功使用它的详细信息!
2000 年初,CollabNet, Inc.(现称为 Digital.ai,https://digital.ai)开始寻找开发人员来编写 CVS 的替代品。CollabNet 提供了[3] 一套名为 CollabNet Enterprise Edition (CEE) 的协作软件套件,其中一个组件是版本控制。虽然 CEE 使用 CVS 作为其最初的版本控制系统,但 CVS 的局限性从一开始就显而易见,CollabNet 知道最终必须找到更好的东西。不幸的是,CVS 已经成为开源世界中的事实上的标准,主要是因为没有更好的东西,至少在免费许可下没有。因此,CollabNet 决定从头开始编写一个新的版本控制系统,保留 CVS 的基本思想,但没有错误和错误功能。
2000 年 2 月,他们联系了 Karl Fogel,他是《使用 CVS 进行开源开发》(Coriolis,1999)一书的作者,并询问他是否愿意参与这个新项目。巧合的是,当时 Karl 已经和他的朋友 Jim Blandy 讨论了新版本控制系统的设计。1995 年,两人共同创办了 Cyclic Software,一家提供 CVS 支持合同的公司,尽管后来他们出售了这家公司,但他们仍然在日常工作中使用 CVS。他们对 CVS 的沮丧促使 Jim 认真思考管理版本化数据的更好方法,他已经想出了 Subversion 的名称,以及 Subversion 数据存储的基本设计。当 CollabNet 打电话时,Karl 立即同意参与该项目,Jim 也说服了他的雇主 Red Hat Software,让他无限期地加入该项目。CollabNet 聘请了 Karl 和 Ben Collins-Sussman,详细的设计工作于 2000 年 5 月开始。在 Brian Behlendorf 和 Jason Robbins(CollabNet)以及 Greg Stein(当时是活跃于 WebDAV/DeltaV 规范流程的独立开发者)的推动下,Subversion 迅速吸引了一批活跃的开发者社区。事实证明,许多人遇到了与 CVS 相同的令人沮丧的经历,并欢迎有机会最终解决这个问题。
最初的设计团队设定了一些简单的目标。他们不想在版本控制方法上开拓新领域,他们只是想修复 CVS。他们决定 Subversion 将匹配 CVS 的功能并保留相同的开发模型,但不会复制 CVS 最明显的缺陷。虽然它不需要成为 CVS 的直接替代品,但它应该足够相似,以便任何 CVS 用户都可以轻松地进行切换。
经过 14 个月的编码,Subversion 在 2001 年 8 月 31 日成为“自托管”。也就是说,Subversion 开发人员停止使用 CVS 管理 Subversion 自己的源代码,转而使用 Subversion。
虽然 CollabNet 启动了该项目,并且仍然为大部分工作提供资金(它支付了几位全职 Subversion 开发人员的薪水),但 Subversion 的运行方式与大多数开源项目一样,由一套松散的、透明的规则管理,这些规则鼓励精英统治。2009 年,CollabNet 与 Subversion 开发人员合作,将 Subversion 项目整合到 Apache 软件基金会 (ASF),这是世界上最知名的开源项目集合之一。Subversion 的技术根源、社区优先事项和开发实践非常适合 ASF,ASF 的许多成员已经是活跃的 Subversion 贡献者。2010 年初,Subversion 被完全纳入 ASF 的顶级项目家族,其网站迁移至 https://subversion.org.cn,并更名为“Apache Subversion”。
图 1,“Subversion 架构” 说明了 Subversion 设计的“高空”视图。
在一端是 Subversion 仓库,它保存着所有版本化的数据。在另一端是您的 Subversion 客户端程序,它管理着这些版本化数据的一部分的本地反映。在这两个极端之间,通过仓库访问 (RA) 层有多条路线,其中一些路线跨越计算机网络并通过网络服务器访问仓库,另一些路线则完全绕过网络并直接访问仓库。
Subversion 安装后,包含许多不同的部分。以下是对您获得的内容的简要概述。如果简短的描述让您一头雾水,请不要惊慌——本书中还有大量页面专门用于消除这种困惑。
命令行客户端程序
一个用于报告工作副本状态(以项目存在的修订版表示)的程序
一个用于直接检查 Subversion 仓库的工具
一个用于创建、调整或修复 Subversion 仓库的工具
Apache HTTP Server 的插件模块,用于通过网络让其他人访问您的仓库
一个自定义的独立服务器程序,可以作为守护进程运行或通过 SSH 调用;另一种通过网络让其他人访问您的仓库的方式
一个用于过滤 Subversion 仓库转储流的程序
一个用于将一个仓库增量镜像到另一个仓库的程序
一个用于通过网络执行仓库历史记录转储和加载的程序
本书的第一版由 O'Reilly Media 于 2004 年出版,当时 Subversion 刚刚发布 1.0 版。从那时起,Subversion 项目一直在继续发布软件的新主要版本。以下是自 Subversion 1.0 版以来主要新变化的简要概述。请注意,这不是一个完整的列表;有关完整详细信息,请访问 Subversion 网站 https://subversion.org.cn。
1.1 版本引入了 FSFS,这是一种用于存储库的平面文件存储库选项。虽然 Berkeley DB 后端仍然被广泛使用和支持,但 FSFS 由于其低入门门槛和最小的维护要求,已成为新创建存储库的默认选择。此版本还引入了将符号链接置于版本控制之下、自动转义 URL 和本地化用户界面等功能。
1.2 版本引入了在文件上创建服务器端锁的功能,从而对某些资源的提交访问进行序列化。虽然 Subversion 仍然是一个本质上并发版本控制系统,但某些类型的二进制文件(例如艺术资产)无法合并在一起。锁定功能满足了对这些资源进行版本控制和保护的需要。随着锁定的引入,还带来了完整的 WebDAV 自动版本控制实现,允许将 Subversion 存储库作为网络文件夹挂载。最后,Subversion 1.2 开始使用一种新的、更快的二进制差异算法来压缩和检索文件的旧版本。
1.3 版本为 svnserve 服务器带来了基于路径的授权控制,与以前仅在 Apache 服务器中找到的功能相匹配。然而,Apache 服务器本身获得了一些新的日志记录功能,而 Subversion 与其他语言的 API 绑定也取得了长足进步。
1.4 版本引入了一个全新的工具——svnsync——用于在网络上进行单向存储库复制。工作副本元数据的很大一部分进行了改造,不再使用 XML(从而提高了客户端速度),而 Berkeley DB 存储库后端获得了在服务器崩溃后自动恢复自身的能力。
1.5 版本的发布比之前的版本花费了更长的时间,但其最主要的特性是巨大的:半自动化的分支和合并跟踪。这对用户来说是一个巨大的福音,并将 Subversion 推向了 CVS 的能力之外,跻身于 Perforce 和 ClearCase 等商业竞争对手的行列。Subversion 1.5 还引入了一系列其他以用户为中心的特性,例如交互式解决文件冲突、稀疏检出、客户端管理变更列表、强大的外部定义新语法以及对 svnserve 服务器的 SASL 身份验证支持。
1.6 版本通过引入树冲突,继续使分支和合并更加健壮,并对其他几个现有特性进行了改进:更多交互式冲突解决选项;稀疏检出的去嵌套和完全排除支持;基于文件的外部定义;以及类似于 mod_dav_svn 提供的操作日志支持。此外,命令行客户端引入了新的快捷语法来引用 Subversion 存储库 URL。
1.7 版本主要是为了交付对现有 Subversion 组件进行的两次大型管道改造。其中最大且影响最深远的是所谓的 “WC-NG”——对 libsvn_wc 工作副本管理库的完全重写。第二个变化是引入了更简洁的 HTTP 协议,用于 Subversion 客户端/服务器交互。Subversion 1.7 还提供了一些额外的特性、许多错误修复以及一些显著的性能改进。