本文档旨在描述 Apache™ Subversion® 的 1.7.x 系列。如果您运行的是其他版本的 Subversion,强烈建议您访问 https://svnbook.subversion.org.cn/ 并查阅适合您 Subversion 版本的文档。
另一个常见的版本控制概念是标签。标签只是项目在某个时间点的“快照”。在 Subversion 中,这个概念似乎无处不在。每个仓库版本都是一个快照,即每次提交后文件系统的快照。
然而,人们通常希望为标签赋予更人性化的名称,例如 release-1.0
。他们还希望对文件系统的较小子目录进行快照。毕竟,记住软件的 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 902.
此示例假设 /calc/tags
目录已存在。(如果不存在,您可以使用 svn mkdir 创建它。)复制完成后,新的 release-1.0
目录将永远是 /trunk
目录在您进行复制时 HEAD
版本中的状态的快照。当然,您可能希望更精确地指定要复制的版本,以防其他人可能在您没有注意的情况下对项目进行了更改。因此,如果您知道 /calc/trunk
的版本 901 正是您想要的快照,您可以通过将 -r 901
传递给 svn copy 命令来指定它。
等等,这不是和创建分支一样的过程吗?没错,实际上是一样的。在 Subversion 中,标签和分支之间没有区别。两者都只是通过复制创建的普通目录。就像分支一样,复制的目录之所以被称为“标签”,是因为**人类**决定将其视为标签:只要没有人提交到该目录,它就永远保持为快照。如果人们开始提交到该目录,它就变成了分支。
如果您是仓库管理员,您可以采用两种方法来管理标签。第一种方法是“放任自流”:作为项目策略的一部分,决定标签的存放位置,并确保所有用户都知道如何处理他们复制的目录。(也就是说,确保他们知道不要提交到这些目录。)第二种方法更加谨慎:您可以使用 Subversion 提供的访问控制脚本之一来阻止任何人除了在标签区域创建新副本之外的任何操作(参见第 6 章,服务器配置)。但是,谨慎的方法通常没有必要。如果用户不小心将更改提交到标签目录,您可以像上一节中讨论的那样简单地撤消更改。毕竟,这就是版本控制!
有时您可能需要一个比单个目录在单个修订版本中更复杂的“快照”。
例如,假设您的项目比我们的 calc
示例大得多:假设它包含许多子目录和更多文件。在您的工作过程中,您可能会决定需要创建一个工作副本,该副本旨在具有特定的功能和错误修复。您可以通过选择性地将文件或目录回溯到特定修订版本(使用 svn update 以及 -r
选项)来实现这一点,通过将文件和目录切换到特定分支(使用 svn switch)来实现这一点,甚至可以通过进行大量本地更改来实现这一点。完成后,您的工作副本将成为来自不同修订版本的仓库位置的大杂烩。但是经过测试后,您知道这是您需要标记的精确数据组合。
是时候创建快照了。将一个 URL 复制到另一个 URL 在这里不起作用。在这种情况下,您希望创建工作副本的精确排列的快照,并将其存储在仓库中。幸运的是,svn copy 实际上有四种不同的用途(您可以在第 9 章,Subversion 完整参考中阅读),包括将工作副本树复制到仓库的能力。
$ ls my-working-copy/ $ svn copy my-working-copy \ http://svn.example.com/repos/calc/tags/mytag \ -m "Tag my existing working copy state." Committed revision 940.
现在仓库中有一个新的目录,/calc/tags/mytag
,它是工作副本的精确快照——混合修订版本、URL、本地更改等等。
其他用户已经找到了此功能的有趣用途。有时会出现这种情况,您对工作副本进行了一些本地更改,并且希望合作者看到这些更改。与其运行 svn diff 并发送补丁文件(它不会捕获目录或符号链接更改),不如使用 svn copy 将工作副本“上传”到仓库的私有区域。然后,您的合作者可以签出工作副本的逐字副本,或者使用 svn merge 来接收您的精确更改。
虽然这是一种快速上传工作副本快照的好方法,但请注意,这不是创建分支的理想方式。分支创建应该是一个独立的事件,而这种方法将分支创建与对文件的额外更改混淆在一起,全部在一个修订版本中完成。这使得以后很难将单个修订版本号识别为分支点。