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.

遍历分支

命令 svn switch 切换一个已有的工作副本, 使其映射 到另一个不同的分支. 虽然在使用分支时, 该命令并不是必须的, 但它提供了很 方便的快捷键. 在一个我们讲过的例子里, 当用户创建完私有分支后, 检出了该 分支的工作副本. 现在用户多了一种选择, 用命令 svn switch/calc/trunk 的工作副本映射到新创建的分支:

$ cd calc
$ svn info | grep URL
URL: http://svn.example.com/repos/calc/trunk
Relative URL: ^/calc/trunk
$ svn switch ^/calc/branches/my-calc-branch
U    integer.c
U    button.c
U    Makefile
Updated to revision 341.
$ svn info | grep URL
URL: http://svn.example.com/repos/calc/branches/my-calc-branch
Relative URL: ^/calc/branches/my-calc-branch
$

切换 一个不含有本地修改的工作副本到另一个分支, 最终 得到的工作副本就像是从分支上检出的一样. 使用 svn switch 切换分支通常会更有效率, 因为分支之间的差异通常很小, 服务器只需要发送一 小部分数据, 就可以让工作副本映射到一个新的分支.

svn switch 支持选项 --revision (-r), 因此用户还可以把工作副本切换到分支的其他版本, 并 非只能是 HEAD.

当然, 绝大多数项目都要比例子里的 calc 复杂得多, 而且包含非常多的子目录, Subversion 用户在使用分支时经常遵循一些固定的 步骤:

  1. 把项目的整个 主干 复制到一个新的分支目录.

  2. 只把主干工作副本的 一部分 进行切换, 以映射到另一 个分支.

换句话说, 如果用户知道分支的工作只需要在某个特定的子目录内完成, 他 就可以用 svn switch, 只把这个子目录切换到分支上 (用户甚至可以只切换一个文件!). 通过这种方式, 用户可以继续接收正常的 主干 更新到大部分的工作副本, 但不会更新已切换的部分 (除 非有人向分支提交了修改). 这个特性给 混合的工作副本 添加了新的一个维度—工作副本不仅可以包含混合的版本号, 甚至可以包含 混合的仓库位置.

[提示] 提示

典型情况下, 已切换的子目录和 被切换走的 目录共享相同 的祖先, 但 svn switch 也可以把子目录切换到一个不与 原目录共享祖先的仓库位置, 方法是加上选项 --ignore-ancestry .

即使工作副本内包含了大量的已切换的子目录, 这些子目录来自仓库中不同 位置, 那么工作副本仍然可以正常工作. 更新工作副本时, 各个子目录也会收到 正确的修改; 提交时, 本地修改仍然作为一个单一的原子修改, 被提交到仓库中.

注意, 虽然 Subversion 允许工作副本映射不同的仓库位置, 但这些位置必须 在 同一个 仓库中. Subversion 还不支持跨仓库的交互, 但以后可能会添加这一特性.[40]

[提示] 提示

如果管理员需要修改仓库的 URL, 而仓库是通过 HTTP 进行访问, 那么强烈 建议管理员在配置文件 httpd.conf 添加一个永久的 重定向 (通过配置项 RedirectPermanent), 将旧的 URL 重定向至新的 URL, 这样的话, 当用户仍然使用旧的 URL 访问仓库时, Subversion 客户端就会在错误信息中显示仓库的新 URL. 从 Subversion 1.7 开始, 客户端可以自动地把工作副本重定向至新的 URL.

因为 svn switch 本质上是 svn update 的一个变种, 所以它有着和 svn update 相同的行为: 从服务器接收更新时, 工作副本 的本地修改将被保留.

[提示] 提示

读者是否遇到过这种情形: 在 /trunk 的工作副本 中做了一些复杂的修改, 结果却发现这些修改应该有一个自己的分支, 这时候 用户可以这样做:

$ svn copy http://svn.example.com/repos/calc/trunk \
           http://svn.example.com/repos/calc/branches/newbranch \
           -m "Create branch 'newbranch'."
Committed revision 353.
$ svn switch ^/calc/branches/newbranch
At revision 353.

svn update 一样, svn switch 保留了本地修改. 现在你的工作副本已经映射到了新创建的分支, 如果后面执行 了 svn commit, 修改将会被提交上新创建的分支中.



[40] 然而, 如果服务器的 URL 发生了 改变, 而用户不想丢掉已有的工作副本, 那就可以用 svn relocate , 更多的信息和例子, 见 svn 参考手册—Subversion 命令行客户端svn relocate