### 标签 另一个常见的版本控制系统概念是标签(*tag*),一个标签只是一个项目某一时间的“快照”,在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]( "svn mkdir")),拷贝完成之后,一个表示当时`HEAD`版本的/calc/trunk目录的镜像已经永久的拷贝到`release-1.0`目录。当然,你会希望更精确一点,以防其他人在你不注意的时候提交修改,所以,如果你知道`/calc/trunk`的版本350是你想要的快照,你可以使用**svn copy**加参数 `-r 350`。 但是等一下:标签的产生过程与建立分支是一样的?是的,实际上在Subversion中标签与分支没有区别,都是普通的目录,通过copy命令得到,与分支一样,一个目录之所以是标签只是*人们*决定这样使用它,只要没有人提交这个目录,它永远是一个快照,但如果人们开始提交,它就变成了分支。 如果你管理一个版本库,你有两种方式管理标签,第一种方法是禁止命令:作为项目的政策,我们要决定标签所在的位置,确定所有用户知道如何处理拷贝的目录(也就是确保他们不会提交他们),第二种方法看来很过分:使用访问控制脚本来阻止任何想对标签目录做的非拷贝的操作(见[第6章 *配置服务器*]( "第6章配置服务器"))这种方法通常是不必要的,如果一个人不小心提交了到标签目录一个修改,你可以简单的取消,毕竟这是版本控制啊。 ### 建立复杂的标签 有时候你希望你的“快照”能够很复杂,而不只是一个单独修订版本的一个单独目录。 举个例子,假定你的项目比我们的的例子`calc`大的多:假设它保存了一组子目录和许多文件,在你工作时,你或许决定创建一个包括特定特性和Bug修正的工作拷贝,你可以通过选择性的回溯文件和目录到特定修订版本(使用**svn update -r**)来实现,或者转换文件和目录到特定分支(使用**svn switch**),这样做之后,你的工作拷贝成为版本库不同版本和分支的司令部,但是经过测试,你会知道这是你需要的一种精确数据组合。 是时候进行快照了,拷贝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**来接受你的精确修改。