标签

版本控制的另一个共同的概念是标签(tag)。一个标签只是项目在时间上的“快照”。 在Subversion中,这个概念已经好像无处不在了。每个资料库修订版实际就是一个标签——一次提交后文件系统的一个快照。

然而,人们常想给标签以人更易识别的名字,比如release-1.0。并且他们想做文件系统里较小的子目录的快照。 毕竟,要记住一个软件的release-1.0是修订版4822中一个特定的子目录不那么容易。

创建简单的标签

svn copy再次来拯救我们了。如果你想创建/calc/trunkHEAD修订版中样子的一个精确的快照,那么对它做一个复制:

$ 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目录已经存在。(如果不是这样,参见???)。 在复制完成后,新的release-1.0目录永远是你做复制的那个时间里项目在HEAD修订版 中的样子。当然你可能想更精确的复制某个修订版。如果你知道/calc/trunk的修订版350就是你想要的, 你可以通过传递-r 350svn copy命令来指定它。

等一下!创建标签的过程和我们用来创建分支的过程不一样吧?事实上,他们是一样的。在Subversion中,标签和分支没什么不同。 这两者都是通过复制创建的普通的目录。正如分支一样,复制得来的目录是“标签”的唯一原因是因为人们决定这么看待它:只要没人提交到到这个目录,它永远是一个快照。如果人们开始对它提交,它就成了一个分支。

如果你在管理一个资料库,有两种管理标签的办法。第一种是“放手管理”:作为一个项目政策,决定 你的标签放在哪里,并确认所有的用户知道如何对待他们复制到那儿的目录。(就是说,确认他们知道不要对他们做提交。) 第二个办法更偏执:你可以用随Subversion 一起提供的一个访问控制脚本来阻止任何人在标签区域做除了创建新拷贝外的任何事 (参见第 6 章 服务器配置)。然而这个偏执的办法通常是不必要的。如果用户无意中在一个标签目录上提交了修改,你 可以简单的撤销这些修改,像在前面的章节讨论的那样。毕竟这是版本控制。

创建一个复杂的标签

有时你可能想让你的“快照”更复杂一点,不仅是单个修订版的单个目录。

例如,假设你的项目比我们的例子calc要大得多:比如它包含大量的子目录和更多的文件。 在我们工作过程中,你可能决定你需要创建一个这样的工作副本:它要包含指定的特性和bug修正。 你可以通过把文件和目录有选择的回溯到特定的修订版(大量的使用svn update -r),或者通过把文件和目录切换到特定的分支(利用svn switch)来达到目的。当你完成后,你的工作副本是一个不同修订版的不同资料库位置组成的大杂烩。 在测试后,你就知道它是你需要的数据的精确的组合。  

是时候来做一个快照了。把一个URL复制到另一个在这里行不通。这种情况下,你想对你的工作副本的布局的一个精确的快照并把它存到资料库。 幸运的是,svn copy实际上有四种不同的用法(你在第九章能读到),包括复制一个工作副本树到资料库的能力。

$ 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 copy来“上载” 你的工作副本到资料库的私有区域,而不是执行svn diff并发送一个补丁文件(它不会包含树修改)。然后你的合作者可以检出你的工作副本的一字不差的拷贝, 或使用svn merge来接受你的精确的修改。