Subversion 存储库中的 “分支”,“标签” 和“主干”是什么意思?

在 Subversion(我想是通用存储库)的讨论中,我经常看到这些词。过去几年,我一直在项目中使用 SVN,但我从未完全掌握这些目录的完整概念。

他们的意思是什么?

答案

嗯,不确定我是否同意 Nick re tag 与分支相似。标签只是一个标记

  • 从项目开始到现在, 干线将是开发的主体。

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

  • 标签将是您要保留的主干或分支上的时间点。保留的两个主要原因是:这是软件的主要发行版(无论是 alpha,beta,RC 还是 RTM),或者这是在应用主干上的主要修订之前软件的最稳定点。

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

分支和标记子树通过以下方式与主干区分开来:

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

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

首先,就像 @AndrewFinnell 和 @KenLiu 指出的那样,在 SVN 中,目录名称本身没有任何意义 -“主干,分支和标签” 只是大多数存储库使用的通用约定。并非所有项目都使用所有目录(完全不使用 “标签” 是很普遍的做法),事实上,尽管违反约定通常会造成混乱,但没有什么可以阻止您调用它们。

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

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

  • 分支 :每次发布主要版本时,都会创建一个分支。这样,您就可以进行错误修复并发布新版本,而不必发布最新的功能(可能尚未完成或未经测试)。

  • 标签 :每次发布版本(最终版本,候选发布版(RC)和 Beta 版)时,您都会为其添加标签。这为您提供了当时状态下的代码的时间点副本,允许您在必要的情况下返回并重现任何错误,或者在以前的版本中完全重新发布。 SVN 中的分支和标记是轻量级的 - 在服务器上,它不制作文件的完整副本,只是一个标记说 “这些文件是在此版本中复制的”,仅占用几个字节。考虑到这一点,您永远不必担心为任何已发布的代码创建标签。正如我之前所说,标记通常被省略,取而代之的是,发布版本时,变更日志或其他文档阐明了修订版本号。


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

  • trunk /- 开发版本,即将发布 1.0
  • 分支机构 /- 空

1.0.0 完成后,将中继分支到新的 “1.0” 分支,并创建 “1.0.0” 标签。现在,关于最终将是 1.1 的工作将继续进行。

  • trunk /- 开发版本, 即将发布 1.1
  • branchs / 1.0-1.0.0 发行版本
  • 标签 / 1.0.0-1.0.0 发行版本

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

  • trunk /- 开发版本,即将发布 1.1
  • 分支机构/1.0 - 即将发布的 1.0.1 版本
  • 标签 / 1.0.0-1.0.0 发行版本

一旦发现足够的错误(或可能是一个严重的错误),便决定执行 1.0.1 版本。因此,您可以从 1.0 分支中创建一个标记 “1.0.1”,然后释放代码。此时,主干将包含 1.1,而 “1.0” 分支包含 1.0.1 代码。下次发布对 1.0 的更新时,它将是 1.0.2。

  • trunk /- 开发版本,即将发布 1.1
  • 分支机构/1.0 - 即将发布的 1.0.2
  • 标签 / 1.0.0-1.0.0 发行版本
  • 标签 / 1.0.1-1.0.1 发行版本

最终,您几乎已经准备好发布 1.1,但是您想先进行 Beta 测试。在这种情况下,您可能会执行 “1.1” 分支和 “1.1beta1” 标记。现在,将在主干中继续进行关于 1.2(或 2.0)的工作,而在 “1.1” 分支中继续进行关于 1.1 的工作。

  • trunk /- 开发版本, 即将发布 1.2
  • 分支机构 / 1.0 - 即将发布的 1.0.2
  • 分支机构 / 1.1 - 即将发布的 1.1.0 版本
  • 标签 / 1.0.0-1.0.0 发行版本
  • 标签 / 1.0.1-1.0.1 发行版本
  • 标签 / 1.1beta1-1.1 beta 1 发行版本

一旦发布了 1.1 最终版,就可以从 “1.1” 分支中执行 “1.1” 标签。

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


分支的另一种用途是用于功能。在这里,您可以分支干线(或其中一个发布分支),并单独开发新功能。功能完成后,将其合并回去并删除分支。

  • trunk /- 开发版本,即将发布 1.2
  • 分支机构 / 1.1 - 即将发布的 1.1.0 版本
  • 分支 / ui 重写 - 实验功能分支

这样的想法是,当您正在从事破坏性的工作(可能阻碍或干扰他人的工作),正在尝试的工作(甚至可能无法完成工作)或可能需要很长时间时(而且,当您准备从主干分支 1.2 时,如果担心它支撑着 1.2 版本),您可以在分支中单独进行操作。通常,您可以通过始终将更改合并到主干中来使其保持最新状态,从而在完成后更易于重新集成(合并回主干)。


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

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

在此处输入图片说明

在此图中, main是主干, rel1-maint是分支, 1.0是标签。

通常, (与工具无关的视图)分支是用于并行开发的机制。一个 SCM 可以有 0 到 n 个分支。 Subversion 有 0。

  • TrunkSubversion 推荐的主要分支,但绝不强迫您创建它。您可以将其称为 “主要” 或 “发布”,也可以根本没有!

  • 分支代表开发工作。永远不要以资源(例如 “vonc_branch”)为名,而要以:

    • 目的 “myProject_dev” 或 “myProject_Merge”
    • 发布边界'myProjetc1.0_dev' 或 myProject2.3_Merge'或'myProject6..2_Patch1'...
  • 标记是文件的快照,以便轻松返回到该状态。 问题是 Subversion 中的 tag 和 branch 相同 。我绝对会推荐偏执的方法:

    您可以使用 Subversion 随附的一种访问控制脚本来阻止任何人执行任何操作,除了在标记区域中创建新副本。

标签是最终的。它的内容永远不会改变。决不。曾经您在发行说明中忘了一行吗?创建一个新标签。过时或删除旧的。

现在,我读了很多有关 “将这样的分支合并到这样的分支中,然后最终合并到主干分支中” 的文章。这称为合并工作流 ,这里没有强制要求 。并不是因为您有主干分支,所以您必须合并任何内容。

按照惯例,主干分支可以代表开发的当前状态,但这是针对简单的顺序项目的,即具有以下内容的项目:

  • 没有 “预先” 开发(用于准备下一个下一个版本,暗示这些更改与当前的 “trunk” 开发不兼容)
  • 无需大量重构(用于测试新的技术选择)
  • 无需长期维护以前的版本

因为使用这些场景中的一个(或全部),您将获得四个 “主干”,四个 “当前开发”,而并非您在这些并行开发中所做的所有工作都必须合并回 “主干”。

在 SVN 中,标签和分支确实很相似。

Tag = 定义的时间片,通常用于发布

分支 = 也定义了可以继续进行开发的时间片,通常用于 1.0、1.5、2.0 等主要版本,然后在发布时标记分支。这使您可以继续支持生产版本,同时继续进行主干中的重大更改。

Trunk = 开发工作空间,应在此处进行所有开发,然后将更改从分支版本中合并回去。

它们实际上没有任何正式含义。文件夹是 SVN 的文件夹。它们是组织项目的普遍接受的方式。

  • 主干是您保持开发主线的地方。分支文件夹是您可以在其中创建分支的位置,在简短的帖子中很难解释。

  • 分支是您与干线分开工作的项目子集的副本。可能是针对可能无法进行任何实验的实验,也可能是针对下一个发行版的,以后您将在稳定后将其合并到主干中。

  • 标签文件夹用于创建存储库的标签副本,通常是在发布检查点。

但是就像我说的那样,对于 SVN,文件夹就是文件夹。 branchtrunk和 tag 只是一个约定。

我在自由地使用 “复制” 一词。 SVN 实际上不会在存储库中制作事物的完整副本。

主干是包含最新源代码和功能的开发线。它应该具有最新的错误修复以及添加到项目中的最新功能。

分支通常用于远离主干(或其他开发线)执行某些操作,否则将破坏构建。新功能通常建在分支中,然后合并回主干。分支通常包含未必为其分支开发线批准的代码。例如,程序员可以对分支中的某些内容进行优化,并且一旦优化令人满意就只能合并回开发行中。

标签是特定时间存储库的快照。在这些方面不应该发展。它们最常用于复制发布给客户端的内容,以便您可以轻松访问客户端使用的内容。

这是一个非常好的存储库指南的链接:

维基百科中的文章也值得一读。

现在是关于软件开发的事情,对任何事情都没有统一的知识,每个人似乎都有自己的方式,但这是因为无论如何这是一门相对较年轻的学科。

这是我简单的方式,

trunk-主干目录包含最新的,批准的和合并的工作体。与许多人所承认的相反,我的后备箱仅用于清洁,整洁,经过批准的工作,而不是用于开发区域,而是用于发布区域。

在某个给定的时间点,当中继线似乎都准备好释放时,便会对其进行标记和释放。

分支 - 分支目录包含实验和正在进行的工作。分支机构下的工作会一直待在那里,直到批准合并到主干中为止。对我来说,这是完成所有工作的区域。

例如:对于产品的第五轮开发,我可以有一个迭代 5分支,对于第九轮实验,可以有一个原型 9分支,依此类推。

标签 - 标签目录包含批准的分支和主干版本的快照。每当批准分支合并到主干中或发布主干时,都会在标签下创建批准的分支或主干发布的快照。

我想有了标签,我可以很容易地在时间上来回跳动来指出兴趣。

当我查阅《 OpenCV 2 计算机视觉应用程序设计指南》 作者的网站时,发现了关于 SVN 的出色教程,我认为应该分享。

他提供了有关如何使用 SVN 以及 “trunk”,“tag” 和 “branch” 的含义的教程。

直接从他的教程中引用:

您的团队当前正在使用的软件项目的当前版本通常位于名为trunk的目录下。随着项目的发展,开发人员将更新该版本的修复错误,添加新功能)并在该目录下提交其更改。

在任何给定的时间点,您可能都希望冻结版本并捕获软件快照,就像在开发的当前阶段一样。这通常对应于您的软件的正式版本,例如,您将交付给客户的版本。这些快照位于项目的标签目录下。

最后,在某个时候为您的软件创建新的开发线通常很有用。例如,当您希望测试替代实现时必须进行修改,但是您不希望将这些更改提交给主项目,直到您决定是否采用新解决方案时,就会发生这种情况。然后,主要团队可以继续从事该项目,而其他开发人员则从事原型工作。您可以将项目的这些新开发线放在一个名为branchs的目录下。

主干目录是您可能最熟悉的目录,因为它用于保存最新更改。您的主要代码库应该在主干中。

分支目录用于保存分支(无论分支如何)。

标签目录主要用于标记一组文件。您可以针对发行版(例如发行版)执行此操作,在该发行版中,您希望 “1.0” 成为这些修订版的这些文件,而希望 “1.1” 成为这些修订版的这些文件。标记一旦制成,通常就不会对其进行修改。有关标签的更多信息,请参见第 4 章。分支和合并 (在Subversion 的 Version Control 中 )。