Subversion仓库中的“分支”、“标签”和“主干”是什么意思?

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

它们是什么意思?

454996 次浏览

在SVN中,标签和分支非常相似。

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

=也是一个定义好的切片,可以继续开发,通常用于主要版本,如1.0、1.5、2.0等,然后当你发布时,你标记分支。这允许你继续支持生产版本,同时推进主干的重大变化

主干=开发工作空间,这是所有开发都应该发生的地方,然后从分支版本合并回来的更改。

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

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

  • 分支是你与主干分开工作的项目子集的副本。也许它用于可能不会去任何地方的实验,或者它用于下一个版本,当它变得稳定时,你将稍后合并回主干。

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

但就像我说的,对SVN来说,文件夹就是文件夹。branchtrunk和标签只是一个约定。

我大量使用“复制”这个词。SVN实际上并没有完整复制存储库中的内容。

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

分支目录用于保存您的分支,无论它们是什么。

标签目录基本上是用于标记一组特定的文件。您可以对诸如版本之类的东西执行此操作,其中您希望“1.0”是这些修订版中的这些文件,而“1.1”是这些修订版中的这些文件。您通常不会修改标记。有关标记的更多信息,请参阅第4章分支和合并(在Subversion版本控制中)。

我不确定“标签”是什么,但分支是一个相当常见的源代码控制概念。

基本上,分支是在不影响主干的情况下处理代码更改的一种方式。假设你想添加一个相当复杂的新功能。你希望能够在做出更改时签入它们,但在完成该功能之前不希望它影响主干。

首先你要创建一个分支。这基本上是你创建分支时主干的副本。然后你要在分支中完成所有工作。分支中的任何更改都不会影响主干,所以主干仍然可用,允许其他人继续在那里工作(比如修复错误或进行小的增强)。一旦你的功能完成,你就会将分支集成回主干。这将把你所有的更改从分支移动到主干。

人们使用分支有许多模式。如果你的产品同时支持多个主要版本,通常每个版本都将是一个分支。在我工作的地方,我们有QA分支和生产分支。在将代码发布到QA分支之前,我们将更改集成到QA分支,然后从那里部署。当发布到生产时,我们从QA分支集成到生产分支,所以我们知道生产中运行的代码与QA测试的相同。

这是维基百科分支条目,因为他们可能比我更好地解释事情。:)

嗯,我不确定我是否同意尼克的标签类似于树枝。标签只是一个标记

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

  • 分支将是来自主干中某个点的代码的副本,用于对代码应用重大更改,同时保持主干中代码的完整性。如果重大更改按计划工作,通常会将它们合并回主干。

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

在开源项目中,项目干系人不接受的主要分支可以成为叉子的基础——例如,与其他源代码共享共同起源的完全独立的项目。

分支和标记子树与主干的区别如下:

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

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

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

分支通常用于在主干(或其他开发线)之外做一些否则会成为打破构建的事情。新功能通常在分支中构建,然后合并回主干。分支通常包含不一定被其分支的开发线批准的代码。例如,程序员可以在分支中尝试对某些东西进行优化,只有在优化令人满意后才合并回开发线。

标签是存储库在特定时间的快照。不应该在这些上进行开发。它们最常用于获取发布给客户端的内容的副本,以便您可以轻松访问客户端正在使用的内容。

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

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

除了尼克所说的,你可以在流式线:并行软件开发的分支模式找到更多

输入图片描述

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

我认为一些混淆来自标签的概念和SVN中实现的区别。对SVN来说,标签是一个分支,它是一个副本。修改标签被认为是错误的,事实上,如果你试图修改路径中带有…/tags/…的任何东西,像TortoiseSVN这样的工具会警告你。

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

我想这就是人们通常所说的“标签”。但在Subversion中:

它们实际上没有任何正式的含义。文件夹是SVN的文件夹。

我觉得相当混乱:一个对分支或标签一无所知的版本控制系统。从实现的角度来看,我认为Subversion创建“副本”的方式非常聪明,但我必须了解它,我称之为泄漏的抽象

或者也许我只是使用CVS太久了。

首先,正如@AndrewFinnell和@KenLiu指出的那样,在SVN中,目录名称本身没有任何意义——“主干、分支和标签”只是大多数存储库使用的常见约定。并非所有项目都使用所有目录(根本不使用“标签”是相当常见的),事实上,没有什么能阻止你随意调用它们,尽管打破约定通常会令人困惑。

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

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

  • 分支:每次你发布一个主要版本,它都会创建一个分支。这允许你做bug修复并制作一个新版本,而不必发布最新的-可能未完成或未经测试的-功能。

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


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

  • 主干/-开发版本,即将成为1.0
  • 分支/-空

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

  • 主干/-开发版本,快到1.1了
  • 分支/1.0-1.0.0发布版本
  • 标签/1.0.0-1.0.0发布版本

你在代码中遇到一些错误,并将其修复在主干中,然后将修复合并到1.0分支。你也可以做相反的事情,修复1.0分支中的错误,然后将它们合并回主干,但通常项目坚持单向合并只是为了减少遗漏某些东西的机会。有时bug只能在1.0中修复,因为它在1.1中已经过时了。这并不重要:你只想确保1.1发布时不会带有1.0中修复的相同错误。

  • 主干/-开发版本,即将成为1.1
  • 分支/1.0-即将发布
  • 标签/1.0.0-1.0.0发布版本

一旦你发现了足够多的bug(或者一个关键的bug),你就决定发布1.0.1。所以你从1.0分支制作了一个标签“1.0.1”,并发布代码。此时,主干将包含1.1,“1.0”分支包含1.0.1代码。下次你发布1.0的更新时,它将是1.0.2。

  • 主干/-开发版本,即将成为1.1
  • 分支/1.0-即将发布
  • 标签/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”分支中继续。

  • 主干/-开发版本,快到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和主干)之间移植bug修复程序。重要的是,对于您正在维护的软件的每个主版本,您都有一个分支包含该版本的最新版本代码。


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

  • 主干/-开发版本,即将成为1.2
  • 分支/1.1-即将发布的1.1.0版本
  • 分支/用户界面-重写-实验特性分支

这个想法是当你在做一些破坏性的东西(会阻碍或干扰其他人做他们的工作)、一些实验性的东西(甚至可能不会进入),或者可能只是需要很长时间的东西(你担心当你准备从主干分支1.2时,它会阻碍1.2的发布),你可以在分支中隔离地做。通常,你通过一直将更改合并到主干中来保持它与主干的最新,这使得当你完成时更容易重新集成(合并回主干)。


另请注意,我在这里使用的版本控制方案只是众多方案中的一个。一些团队会bug修复/维护版本作为1.1、1.2等,以及主要更改作为1. x、2. x等。这里的用法是相同的,但你可以将分支命名为“1”或“1. x”而不是“1.0”或“1.0. x”。(此外,0是如何处理版本号的好指南)。

总的来说(与工具无关的观点),分支是用于并行开发的机制。SCM可以有0到n个分支。Subversion有0。

  • Trunk是Subversion推荐的一个主分支

  • 代表开发工作。它不应该以资源命名(如“vonc_branch”),而应该以:

    • 目的“myProject_dev”或“myProject_Merge”
    • 发布周界'myProjetc1.0_dev'或'myProject2.3_Merge'或'myProject6…2_Patch1'…
  • Tag是文件的快照,以便轻松返回该状态。问题是标签和分支在Subversion中是一样的.我肯定会推荐偏执的方法:

    您可以使用Subversion提供的权限改造脚本之一来防止任何人执行任何操作,但在标签区域中创建新副本。

标签是最终的。它的内容永远不应该改变。永远。永远。你忘记了发行说明中的一行?创建一个新标签。过时或删除旧标签。

现在,我读了很多关于“在某某分支中合并某某,然后最后在主干分支中”的内容。这被称为合并工作流,还有这里没有强制要求。这并不是因为你有一个主干分支,你必须合并回来任何东西。

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

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

因为有了这些场景中的一个(或全部),你会得到四个“主干”,四个“当前开发”,而不是你在这些并行开发中所做的一切都必须合并回“主干”中。

这就是软件开发的问题,没有一致的知识,每个人似乎都有自己的方式,但那是因为它是一个相对年轻的学科。

这是我简单的方法,

主干-主干目录包含最新的、批准的和合并的工作主体。与许多人承认的相反,我的主干仅用于干净、整洁、批准的工作,并且不是开发区域,而是发布区域。

在某个给定的时间点,当主干似乎已经准备好释放时,它就会被标记并释放。

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

例如:我可以在产品的第五轮开发中使用迭代-5分支,在第九轮实验中使用样机-9分支,依此类推。

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

我想有了标签,我可以很容易地在时间中来回跳来跳去。

每个人的定义都略有不同的原因之一是Subversion实现了对分支和标签的支持。Subversion基本上是说:我们看了全功能分支和标签在其他系统中并没有发现它们有用,所以我们没有实现任何东西。只需将副本复制到具有名称的新目录中约定而是。然后当然每个人都可以自由地有稍微不同的约定。要理解真正标签和纯粹的复制+命名约定之间的区别参见维基百科条目Subversion标签和分支

当我在查找OpenCV 2计算机视觉应用程序编程食谱作者的网站时,我发现了这个关于SVN的很棒的教程,我想我应该分享。

他有一个关于如何使用SVN的教程,以及短语“主干”、“标签”和“分支”的含义。

直接引用他的教程:

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

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

最后,在某些时候为您的软件创建一条新的开发线通常是有用的。例如,当您希望测试一个替代实现时,您必须修改您的软件,但在决定是否采用新解决方案之前,您不想将这些更改提交到主项目。然后,主团队可以在其他开发人员处理原型的同时继续处理项目。您可以将项目的这些新开发线放在名为分支的目录下。

主干:在敏捷的每个Sprint完成后,我们会推出一个部分可交付的产品。这些版本保存在主干中。

分支:每个正在进行的Sprint的所有并行开发代码都保存在分支中。

标签:每次我们发布一个部分可交付的产品测试版时,我们都会为它做一个标签。这给了我们当时可用的代码,如果在开发过程中的某个时候需要,允许我们回到那个状态。

对于熟悉GIT的人来说,GIT中的master相当于SVN中的主干。

分支和标签在GIT和SVN中具有相同的术语。