本手册旨在描述 Subversion 1.4。如果您使用的是较新版本的 Subversion,我们强烈建议您访问 https://svnbook.subversion.org.cn/ 并查阅与您 Subversion 版本相匹配的版本手册。
版本控制系统的核心任务是支持协作编辑和共享数据。但不同的系统使用不同的策略来实现这一目标。了解这些不同的策略很重要,原因有二。首先,它将帮助您比较和对比现有的版本控制系统,以防您遇到类似于 Subversion 的其他系统。除此之外,它还将帮助您更有效地使用 Subversion,因为 Subversion 本身支持几种不同的工作方式。
所有版本控制系统都必须解决同一个基本问题:系统如何允许用户共享信息,同时防止他们意外地踩到对方的脚?用户很容易意外地覆盖掉对方在仓库中的更改。
考虑 图 1.2,“要避免的问题” 中所示的场景。假设我们有两名同事,Harry 和 Sally。他们都决定同时编辑同一个仓库文件。如果 Harry 首先将他的更改保存到仓库中,那么(几分钟后)Sally 可能会意外地用她自己的新版本文件覆盖这些更改。虽然 Harry 的文件版本不会永远丢失(因为系统会记录每次更改),但 Harry 做出的任何更改 都不会 出现在 Sally 的新版本文件中,因为她最初没有看到 Harry 的更改。Harry 的工作实际上还是丢失了——或者至少从文件的最新版本中消失了——而且可能是意外造成的。这绝对是我们想要避免的情况!
许多版本控制系统使用 锁定-修改-解锁 模型来解决多个作者覆盖彼此工作的问题。在这个模型中,仓库一次只允许一个人更改文件。这种排他性策略是通过锁来管理的。Harry 必须在开始对文件进行更改之前“锁定”该文件。如果 Harry 锁定了一个文件,那么 Sally 就无法锁定该文件,因此也无法对该文件进行任何更改。她只能读取该文件,并等待 Harry 完成更改并释放锁定。Harry 解锁该文件后,Sally 可以通过锁定和编辑该文件来轮流操作。 图 1.3,“锁定-修改-解锁解决方案” 演示了这个简单的解决方案。
锁定-修改-解锁模型的问题在于它有点限制性,并且通常会成为用户的障碍
锁定可能会导致管理问题。 有时候 Harry 会锁定一个文件,然后忘记了它。与此同时,Sally 还在等待编辑该文件,她的手被绑住了。然后 Harry 去度假了。现在 Sally 必须找管理员来释放 Harry 的锁定。这种情况最终会导致很多不必要的延迟和时间浪费。
锁定可能会导致不必要的序列化。 如果 Harry 正在编辑文本文件的开头,而 Sally 只想编辑同一个文件的结尾呢?这些更改根本没有重叠。他们可以轻松地同时编辑该文件,并且不会造成太大损害,假设更改被正确地合并在一起。在这种情况下,他们不需要轮流操作。
锁定可能会造成虚假的安全感。 假设 Harry 锁定并编辑文件 A,而 Sally 同时锁定并编辑文件 B。但如果 A 和 B 互相依赖,并且对每个文件的更改在语义上不兼容呢?突然之间 A 和 B 就不能一起工作了。锁定系统无法阻止这个问题——但它在某种程度上提供了一种虚假的安全感。Harry 和 Sally 很容易想象,通过锁定文件,每个人都开始了一个安全、隔离的任务,因此不需要在早期讨论他们不兼容的更改。锁定通常成为真实沟通的替代品。
Subversion、CVS 和许多其他版本控制系统使用 复制-修改-合并 模型作为锁定的替代方案。在这个模型中,每个用户的客户端都会联系项目仓库,并创建一个私人的 工作副本——仓库文件和目录的本地镜像。用户随后会同时且独立地工作,修改他们私人的副本。最后,私人的副本被合并到一个新的、最终版本中。版本控制系统通常会协助合并,但最终还是由人来负责确保合并正确完成。
举个例子。假设 Harry 和 Sally 都从仓库中创建了同一个项目的副本,并创建了工作副本。他们同时工作,并对副本中的同一个文件 A 进行更改。Sally 首先将她的更改保存到仓库中。当 Harry 稍后尝试保存他的更改时,仓库会通知他他的文件 A 已过期。换句话说,仓库中的文件 A 自他上次复制它以来已经发生了某些更改。所以 Harry 要求他的客户端将任何来自仓库的新更改 合并 到他的文件 A 工作副本中。很可能 Sally 的更改不会与他的更改重叠;因此,一旦他将这两组更改集成在一起,他就会将他的工作副本保存回仓库。 图 1.4,“复制-修改-合并解决方案” 和 图 1.5,“复制-修改-合并解决方案(续)” 显示了这个过程。
但如果 Sally 的更改 确实 与 Harry 的更改重叠呢?那该怎么办?这种情况被称为 冲突,这通常不是什么大问题。当 Harry 要求他的客户端将最新的仓库更改合并到他的工作副本中时,他的文件 A 副本会以某种方式被标记为处于冲突状态:他将能够看到两组冲突的更改,并手动选择其中的一组。请注意,软件无法自动解决冲突;只有人类才能够理解并做出必要的智能选择。一旦 Harry 手动解决了重叠的更改——可能是在与 Sally 讨论之后——他就可以安全地将合并后的文件保存回仓库。
复制-修改-合并模型听起来可能有点混乱,但在实践中,它运行得非常顺畅。用户可以并行工作,永远不会互相等待。当他们在同一个文件上工作时,事实证明他们的大多数并发更改根本没有重叠;冲突很少发生。而且解决冲突所需的时间通常远远少于锁定系统所浪费的时间。
归根结底,这一切都归结于一个关键因素:用户沟通。当用户沟通不畅时,语法冲突和语义冲突都会增加。没有哪个系统可以强迫用户完美沟通,也没有哪个系统可以检测到语义冲突。因此,没有必要被锁定系统会阻止冲突的错误安全感所迷惑;实际上,锁定似乎比任何其他事情都更抑制生产力。