协慌网

登录 贡献 社区

Subversion 存储库中 “分支”,“标记” 和“主干”的含义是什么?

我已经在 Subversion(我猜通用存储库)讨论中看到了很多这样的话。在过去的几年里,我一直在为我的项目使用 SVN,但我从未掌握过这些目录的完整概念。

他们的意思是什么?

答案

嗯,不确定我同意 Nick 重新标记类似于分支。标签只是一个标记

  • Trunk将成为开发的主体,源于项目的开始直到现在。

  • 分支将是从主干中的某个点派生的代码的副本,该代码用于对代码进行重大更改,同时保持主干中代码的完整性。如果主要变更按计划运作,它们通常会合并回主干。

  • 标记将是您希望保留的主干或分支上的时间点。保存的两个主要原因是这是软件的主要版本,无论是 alpha 版,beta 版,RC 版还是 RTM 版,或者在应用主干版本修改之前,这是软件中最稳定的一点。

在开源项目中,项目利益相关者不接受主干的主要分支可以成为分支的基础 - 例如,与其他源代码共享共同起源的完全独立的项目。

分支和标记子树在以下方面与主干区分开来:

Subversion 允许系统管理员创建钩子脚本 ,这些脚本在某些事件发生时被触发执行; 例如,将更改提交到存储库。对于典型的 Subversion 存储库实现来说,在创建之后将包含 “/ tag /” 的任何路径视为写保护是很常见的; 最终结果是标签一旦创建,就是不可变的(至少是 “普通” 用户)。这是通过钩子脚本完成的,如果tag是更改对象的父节点,则通过阻止进一步更改来强制执行不变性。

从版本 1.5 开始,Subversion 还增加了与 “分支合并跟踪” 相关的功能,以便提交给分支的更改可以合并回主干,并支持增量的 “智能” 合并。

首先,正如 @AndrewFinnell 和 @KenLiu 指出的那样,在 SVN 中,目录名称本身并不代表什么 - “主干,分支和标签” 只是大多数存储库使用的常见约定。并非所有项目都使用所有目录(根本不使用 “标签”),事实上,没有什么能阻止你将它们称为任何你想要的东西,尽管破坏惯例常常令人困惑。

我将描述分支和标记的最常见使用场景,并给出一个如何使用它们的示例场景。

  • 主干 :主要开发区域。这是您下一个主要版本的代码所在的位置,并且通常具有所有最新功能。

  • 分支 :每次发布主要版本时,都会创建一个分支。这允许您进行错误修复并制作新版本,而无需发布最新的 - 可能未完成或未经测试的功能。

  • 标签 :每次发布版本(最终版本,发布候选版本(RC)和测试版)时,都会为其制作标记。这为您提供了该状态下代码的时间点副本,允许您在过去的版本中返回并重现任何错误,或者完全按照原样重新发布过去的版本。 SVN 中的分支和标签是轻量级的 - 在服务器上,它不会生成文件的完整副本,只是标记 “这些文件在此版本中被复制”,只占用几个字节。考虑到这一点,您永远不应该担心为任何已发布的代码创建标记。正如我之前所说,标签经常被省略,而更改日志或其他文档在发布时会澄清修订号。


例如,假设你开始一个新项目。你开始在 “trunk” 中工作,最终将作为 1.0 版本发布。

  • trunk / - 开发版,很快就会是 1.0
  • 分支 / - 空

1.0.0 完成后,将 trunk 分支到一个新的 “1.0” 分支,并创建一个 “1.0.0” 标记。现在继续研究最终将继续在后备箱中继续使用 1.1。

  • trunk / - 开发版, 很快将是 1.1
  • branches / 1.0 - 1.0.0 发布版本
  • tags / 1.0.0 - 1.0.0 发布版本

您在代码中遇到一些错误,并在 trunk 中修复它们,然后将修复程序合并到 1.0 分支。您也可以执行相反的操作,并修复 1.0 分支中的错误,然后将它们合并回主干,但通常项目坚持单向合并以减少丢失某些内容的机会。有时一个 bug 只能在 1.0 中修复,因为它在 1.1 中已经过时了。这并不重要:您只想确保不使用 1.0 中修复的相同错误发布 1.1。

  • trunk / - 开发版,很快将是 1.1
  • branches / 1.0 - 即将发布的 1.0.1 版本
  • tags / 1.0.0 - 1.0.0 发布版本

一旦找到足够的错误(或者可能是一个关键错误),您就决定发布 1.0.1 版本。因此,您从 1.0 分支创建标记 “1.0.1”,并释放代码。此时,trunk 将包含 1.1 的内容,“1.0” 分支包含 1.0.1 代码。下次将更新发布到 1.0 时,它将是 1.0.2。

  • trunk / - 开发版,很快将是 1.1
  • branches / 1.0 - 即将发布的 1.0.2 版本
  • tags / 1.0.0 - 1.0.0 发布版本
  • tags / 1.0.1 - 1.0.1 发布版本

最终你几乎准备好发布 1.1,但你想先做一个测试版。在这种情况下,您可能会执行 “1.1” 分支和 “1.1beta1” 标记。现在,关于什么是 1.2(或者可能是 2.0)的工作继续在 trunk 中继续工作,但是在 1.1 的分支上继续工作 1.1。

  • trunk / - 开发版, 很快就会是 1.2
  • branches / 1.0 - 即将发布的 1.0.2 版本
  • branches / 1.1 - 即将发布的 1.1.0 版本
  • tags / 1.0.0 - 1.0.0 发布版本
  • tags / 1.0.1 - 1.0.1 发布版本
  • tags / 1.1beta1 - 1.1 beta 1 发行版

一旦你发布了 1.1 final,你就可以从 “1.1” 分支中做一个 “1.1” 标记。

如果您愿意,还可以继续维护 1.0,在所有三个分支(1.0,1.1 和 trunk)之间移植错误。重要的是,对于您正在维护的软件的每个主要版本,您都有一个分支,其中包含该版本的最新版本代码。


分支的另一个用途是用于特征。这是您分支主干(或您的一个发布分支)并单独处理新功能的地方。功能完成后,将其重新合并并删除分支。

  • trunk / - 开发版,很快就会是 1.2
  • branches / 1.1 - 即将发布的 1.1.0 版本
  • branches / ui-rewrite - 实验特征分支

这样做的想法是,当你正在研究破坏性的东西(会妨碍或干扰其他人做他们的工作),实验性的东西(甚至可能没有它),或者可能只是需要很长时间的东西(当你准备好从主干分支 1.2 时,你担心如果它支持 1.2 版本),你可以在分支机构中单独进行。通常,您可以通过将更改合并到主干来使其保持最新状态,这样可以在完成后更轻松地重新集成(合并回主干)。


另请注意,我在这里使用的版本控制方案只是其中之一。有些团队会将错误修复 / 维护版本发布为 1.1,1.2 等,主要更改为 1.x,2.x 等。此处的用法相同,但您可以将分支命名为 “1” 或 “1” .x“而不是”1.0“或”1.0.x“。 (除此之外, 语义版本控制是如何进行版本号的一个很好的指南)。

除了 Nick 所说的,您还可以在Streamed Lines 中找到更多信息:并行软件开发的分支模式

在此输入图像描述

在这个图中, main是 trunk, rel1-maint是分支, 1.0是标签。