本手册旨在介绍 Subversion 1.2 版本。如果您使用的是更新版本的 Subversion,我们强烈建议您访问 https://svnbook.subversion.org.cn/ 并查阅适合您的 Subversion 版本的手册。
另一个常见的版本控制概念是 标签。标签只是项目在某个时间点的“快照”。在 Subversion 中,这个概念似乎无处不在。每个仓库版本都正是如此——在每次提交后文件系统的快照。
然而,人们通常希望为标签赋予更人性化的名称,例如 release-1.0
。他们也希望对文件系统的较小子目录进行快照。毕竟,记住软件的 release-1.0 版本是第 4822 个版本的某个特定子目录并非易事。
再次,svn copy 助您一臂之力。如果您想创建 /calc/trunk
的快照,使其与 HEAD
版本中的内容完全一致,那么您可以复制它
$ svn copy http://svn.example.com/repos/calc/trunk \ http://svn.example.com/repos/calc/tags/release-1.0 \ -m "Tagging the 1.0 release of the 'calc' project." Committed revision 351.
此示例假设 /calc/tags
目录已经存在。(如果不存在,请参阅 svn mkdir)。复制完成后,新的 release-1.0
目录将永远是项目在您进行复制时处于 HEAD
版本时的快照。当然,您可能希望更精确地确定要复制的版本,以防您没注意时其他人可能已经对项目进行了更改。因此,如果您知道 /calc/trunk
的第 350 个版本是您想要的快照,则可以通过向 svn copy 命令传递 -r 350
来指定它。
但是等等:这种标签创建过程和我们用来创建分支的过程不是一样吗?是的,实际上是。在 Subversion 中,标签和分支之间没有区别。两者都只是通过复制创建的普通目录。就像分支一样,复制的目录之所以是“标签”,是因为 人类 决定以这种方式对待它:只要没有人向该目录提交更改,它将永远保持快照状态。如果人们开始向其中提交更改,它将成为分支。
如果您是仓库管理员,您可以采取两种方法来管理标签。第一种方法是“放任自流”:作为项目策略的一部分,确定标签的位置,并确保所有用户都知道如何处理他们在其中复制的目录。(也就是说,确保他们知道不要向其中提交更改。)第二种方法更加谨慎:您可以使用 Subversion 提供的访问控制脚本之一来阻止任何人除了在标签区域中创建新副本之外的任何操作(请参阅 第 6 章,服务器配置)。然而,这种谨慎的方法通常没有必要。如果用户不小心向标签目录提交了更改,您可以根据上一节中的讨论简单地撤销更改。毕竟,这是版本控制。
有时您可能希望您的“快照”比单个目录在单个版本中更复杂。
例如,假设您的项目比我们的 calc
示例大得多:假设它包含许多子目录和更多文件。在工作过程中,您可能会决定需要创建一个工作副本,该工作副本旨在包含特定功能和错误修复。您可以通过将文件或目录有选择地回溯到特定版本(使用 svn update -r)来实现这一点,或者通过将文件和目录切换到特定分支(使用 svn switch)来实现。完成之后,您的工作副本将是来自不同版本的不同仓库位置的混合体。但是经过测试后,您知道它正是您需要的精确数据组合。
现在是创建快照的时候了。将一个 URL 复制到另一个 URL 这里不起作用。在这种情况下,您希望创建工作副本的精确排列快照,并将其存储在仓库中。幸运的是,svn copy 实际上有四种不同的用途(您可以在第 9 章中阅读相关内容),包括将工作副本树复制到仓库中的能力
$ ls my-working-copy/ $ svn copy my-working-copy http://svn.example.com/repos/calc/tags/mytag Committed revision 352.
现在仓库中有一个新的目录 /calc/tags/mytag
,它是工作副本的精确快照——混合版本、URL 和所有内容。
其他用户也发现了此功能的有趣用途。有时您会对工作副本进行一些本地更改,并且希望协作者看到这些更改。而不是运行 svn diff 并发送补丁文件(这不会捕获树更改、符号链接更改或属性更改),而是可以使用 svn copy 将您的工作副本“上传”到仓库的私有区域。然后,您的协作者可以签出工作副本的逐字副本,或者使用 svn merge 来接收您的精确更改。