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 用户困惑的主要来源. 虽然在分支 的创建和管理中, 需要生搬硬套的内容并不复杂, 但是有些用户经常就是否需要创 建分支而犹豫不决. 读者已经看到, Subversion 可以处理常见的分支管理场景, 所以说决定是否需要为项目创建分支在技术上几乎不会产生什么影响, 它的社会 影响反而占据更大的比重. 下面介绍一些在软件项目中使用分支的好处和代价.

使用分支最明显的好处是隔离性. 提交到分支上的修改不会影其他的开发线, 提交到其他开发线的修改也不会影响分支. 利用这点, 开发人员就能安全地在分支 上开发新特性, 对复杂的问题进行修正, 对代码进行重写等. 无论 Sally 在自己 的分支上怎么折腾, Harry 和团队的其他人都可以不受阻碍地继承他们的工作.

利用分支, 我们可以把相关的修改都组织到一个容易识别的集合中, 比如说修 正某个问题的修改可能由多次提交组成, 这些提交的版本号不是连续的. 用户可能 会用人类容易理解的语言描述它们: "版本号 1534, 1543, 1587 和 1588", 很可 能还要在问题跟踪系统中再手工地生成这些号码. 如果修正问题的修改需要被移植 到其他版本中, 则开发人员还要确保不会遗漏任何一个版本号. 但是, 如果把这些 修改都提交到一个独一无二的分支中, 那么在问题跟踪系统或移植修改时, 只需要 引用分支的名字就能确定是哪些提交.

然而, 使用分支的缺点是它的隔离性 与团队的 协作需求相抵触. 取决于同事的工作习惯, 提交到分支上的修改可能不像主线上 的修改那样, 得到非常充分的讨论, 审查与测试. 分支的隔离性会鼓励用户抛弃 版本控制的 最佳做法, 导致版本历史难以在事后进行审查. 在长期存在的分支上工作的开发人员有时候需要付出额外的努力, 以确保分支的 演化方向与同事的保持一致. 对于有些分支而言, 这些缺点都不算是问题, 因为 它们只是试探性的分支, 仅仅是在尝试代码库未来的发展方向, 将来不会被整合 到主线上—单纯的规范不一定会扼杀远见. 但是有一个简单的 事实不容忽视, 那就是代码及其修改如果能得到更多人的审查与理解, 那么对项目 而言通常是有好处的.

并不是说使用分支在技术上一点坏处都没有. 如果我们从更抽象的层次来 看待分支, 就会发现 每次检出仓库的工作副本, 从某种意义上来说其实就是在创建分支, 这只是分支 的一种特殊类型, 它只存在于客户端主机, 不在仓库里, 用 svn update 把仓库的修改同步到分支上—非常像特殊情况下的, 简化版的 svn merge;[44] svn commit 等效于重新整合分支. 所以说从 这个角度来看, Subversion 用户其实一直都在和分支与合并打交道. 不用对 更新与合并之间的相似性过于惊讶, Subversion 短处最集中的地方—也就是 对文件和目录重命名的处理, 以及目录冲突的处理—都会给 svn updatesvn merge 造成麻烦. 不幸的是 svn merge 的麻烦更大, 虽然 svn update 可以看成是 svn merge 的简化形式和 特例, 但一个真正的合并操作既不针对特例, 也不简单. 由于这个原因, 合并操作执行起来比更新更慢, 还要求显式的跟 踪 (通过本章讨论过的属性 svn:mergeinfo) 和历史分析计 算, 而且出错的机会也更多.

分支, 还是不分支? 归根结底还要看开发团队如何把握协作与隔离之间的 平衡.



[44] 实际上, 你 可以 在工作副本中用 svn merge -rLAST_UPDATED_REV:HEAD ., 逐字地把仓库中的自从上一次更新后的修改合并到工作副本.