This text is a work in progress—highly subject to change—and may not accurately describe any released version of the Apache™ Subversion® software. Bookmarking or otherwise referring others to this page is probably not such a smart idea. Please visit http://www.svnbook.com/ for stable versions of this book.
另一个常见的版本控制概念是标签. 标签是项目的一个 “快照”, 它在 Subversion 中到处都是, 因为每一个版本号都对应着提交后, 文件系统的 一个快照.
然而, 用户经常想给标签取一个更人性化的名字, 例如 release-1.0
, 而且用户只想对文件系统的某个子目录做快照, 毕竟人们更容易记住
项目的发布版 1.0 是版本号为 4822 的特定子目录.
创建标签的命令是 svn copy. 如果用户想为
处于 HEAD
的 /calc/trunk
创建一个快照, 就执行:
$ 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
就成为了
/calc/trunk
在复制那一刻的永久快照. 当然, 用户也
可以指定被复制的版本号, 避免其他在用户没有觉察的时候, 向仓库提交了新
的修改. 如果说用户已经知道版本号为 901 的
/calc/trunk
正是自己想要的快照, 就给命令
svn copy 添加选项 -r 901
.
请等一下, 这和创建分支的步骤不是一样的吗? 事实上的确如此. 对于 Subversion 而言, 标签和分支没有区别, 它们都是通过命令 svn copy 创建的目录. 之所以把复制出的目录叫作 “标签 ” 的唯一原因是 用户 已经决定把该目录看成 标签—只要没有人往标签提交修改, 它就永远保持创建时的样子. 如果用户 在创建标签后, 往标签提交了新的修改, 那么从用户的角度来看, 它就变成了 一个分支.
如果读者是仓库的管理员, 那么你有 2 种标签管理方法. 第 1 种是 “放任不管”: 作为一种项目管理策略, 一开始便规定好标签 的存放位置, 确保所有用户都知道如何对待他们复制的目录 (也就是确保他们不 会向标签提交修改). 第 2 种更具有强制性: 使用和 Subversion 配合的 访问控制脚本, 禁止任何人在标签区提交修改, 除了创建新的标签 (见 第 6 章 服务器配置). 第 2 种方法通常是没有必要的, 因 为如果用户不小心向标签提交了修改, 总是可以用之前介绍的方法, 撤消已经 提交的修改.
有时候, 用户可能需要更复杂的 “快照”, 它不仅仅是单独 版本号下的单个目录.
举个例子, 假设你的项目比我们的 calc
庞大得
多: 项目内包含了大量的文件与目录. 在工作过程中, 你可能需要创建一个
含有指定特性和问题修正的工作副本, 创建的方式可以是选择性地把文件或
目录退回到指定的版本 (使用带有选项 -r
的
svn update 命令), 把文件和目录切换到特定的分支
(通过命令 svn switch), 甚至是一连串的本地修改.
创建完毕后, 你的工作副本就变成了一个大杂烩, 但是在测试后, 你确定这
正是你想要创建标签的目标.
是时候创建快照了, 但复制 URL 在这里不起作用. 对于这种情况, 用户 想要的是在仓库中, 为当前状态下的工作副本创建一个快照. 幸运的是 svn copy 的 4 种用法中 (见 svn 参考手册—Subversion 命令行客户端 的 svn copy (cp)), 包含了把工作副本复制到仓库中的能力:
$ 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 diff 无法体现目录或符号链接的变化), 而是用 svn copy 把 当前状态下的工作副本 “上传” 到仓库中的适当位置, 例如你的 私有目录, 然后其他用户就可以用 svn checkout 逐字 拷贝你的工作副本, 或者用 svn merge 接收你做出的修改.
虽然这是上传工作副本快照的好办法, 但要注意的是这 不是 一个创建分支的好办法, 创建分支应该是它本身的事件, 而这种 方法创建的分支混合了额外的修改, 分支的创建和修改都在一个单独的版本号 里, 这样的话我们以后就难确定哪一个版本号才是分支点.