在Subversion版本库中,“branch”,“tag”和“trunk”是什么意思?

我曾经在Subversion(我猜是通用的存储库)讨论过这些词。 过去几年来,我一直在使用SVN来进行项目,但是我从来没有理解这些目录的完整概念。

他们的意思是什么?

嗯,不知道我同意尼克重新标签是类似的一个分支。 标签只是一个标记

  • 树干将成为发展的主体,从项目的开始直到现在。

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

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

在开源项目中,项目干系人未被纳入干系的主要分支可以成为分叉的基础 – 例如完全独立的与其他源代码共同起源的项目。

首先,像@AndrewFinnell和@KenLiu指出的那样,在SVN中,目录名称本身并不意味着什么 – “主干,分支和标签”是大多数存储库使用的常见约定。 并不是所有的项目都使用所有的目录(根本不常用“标签”),事实上,没有任何东西阻止你调用任何你喜欢的东西,尽管打破惯例往往令人困惑。

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

  • 树干 :主要发展区域。 这是您的下一个主要版本的生活的地方,并且通常具有所有最新的功能。

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

  • 标签 :每当你发布一个版本(最终版本,发布候选人(RC)和贝塔斯),你为它做一个标签。 这会为您提供代码的时间点副本,因为它处于该状态,允许您在过去的版本中返回并重新生成任何错误,或重新发布过去的版本。 SVN中的分支和标签是轻量级的 – 在服务器上,它不会完整地拷贝文件,只是一个标记“这些文件在这个版本上复制”,只占用几个字节。 考虑到这一点,你永远不应该关心为任何发布的代码创建一个标签。 正如我刚才所说的,标签经常被省略,相反,更新日志或其他文档会在发布时阐明版本号。


例如,假设您开始一个新项目。 你开始在“trunk”中工作,最终会以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版本的bug,而这个bug已经在1.0版本中修复了。

  • 中继/发展版本,很快就会是1.1
  • 分支/ 1.0 – 即将发布的1.0.1版本
  • 标签/ 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。

  • 中继/发展版本,很快就会是1.1
  • 分支/ 1.0 – 即将到来的1.0.2版本
  • 标签/ 1.0.0 – 1.0.0发布版本
  • 标签/ 1.0.1 – 1.0.1发布版本

最终,你几乎准备好发布1.1,但是你想先做一个测试。 在这种情况下,你可能会做一个“1.1”分支和一个“1.1beta1”标签。 现在,干什么可能是1.2(或者2.0),但在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和中继)之间的错误修复。 重要的是,对于您所维护的每个主要版本的软件,您都有一个分支,其中包含该版本的最新版本。


另一个分支的用途是功能。 这是你分支树干(或你的一个发布分支)的地方,并孤立地处理一个新的功能。 一旦该功能完成,您将它合并回去,并删除分支。

  • 中继/发展版本,很快就会达到1.2
  • 分支机构/ 1.1 – 即将发布的1.1.0版本
  • 分支/用户重写 – 实验功能分支

这样做的想法是,当你正在做一些破坏性的事情(这会阻碍或干扰其他人做他们的工作),一些实验性的(甚至可能不会实现的),或者可能只是需要很长时间的事情(如果你准备好从trunk中分支1.2版本,你会害怕1.2版本),那么你可以在分支机构中单独进行。 一般情况下,通过将更改合并到主干中,可以随时更新主干,从而在完成后更容易重新整合(合并回主干)。


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

除了Nick所说的外,你还可以在Streamed Lines:Parallel Software Development的分支模式中找到更多的东西

在这里输入图像描述

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

一般来说 (工具不可知的视图),一个分支是用于并行开发的机制。 一个SCM可以有0到n个分支。 Subversion有0。

  • Trunk是Subversion 推荐的主要分支,但你绝不会被迫创建它。 你可以称之为“主”或“释放”,或者根本没有!

  • 分支代表了一个开发工作。 它永远不应该被命名后的资源(如'vonc_branch'),但后:

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

    您可以使用Subversion提供的访问控制脚本之一来防止任何人做任何事情,而是在标签区域创建新的副本。

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

现在我读了很多关于“在这样那样的分支上合并回来,然后在干线分支”。 这就是所谓的合并工作流程 ,这里没有任何强制性的 。 这不是因为你有一个主干分支,你必须合并任何东西。

按照惯例,树干分支可以代表你的开发的当前状态,但是对于一个简单的顺序项目来说,这个项目有:

  • 没有“事先”的发展(为了准备下一个版本,暗示这样的变化,它们不符合现在的“干线”发展)
  • 没有大规模的重构(用于测试新的技术选择)
  • 没有以前版本的长期维护

因为有了这些场景中的一个(或全部),你就得到了四条“中继线”,四条“当前发展”,并不是所有在这些平行发展中所做的事情都必须合并到“中继线”中。

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

标记 =一个定义的时间片,通常用于发布

Branch =也是一个定义的时间片,开发可以继续,通常用于1.0,1.5,2.0等主要版本,然后当你释放你的标签的分支。 这使您可以继续支持生产版本,同时继续改变主干

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

他们没有任何正式的意义。 文件夹是SVN的文件夹。 他们是一个普遍接受的方式来组织你的项目。

  • 树干是你保持开发主线的地方。 分支文件夹是您可以创建的地方,分支机构很难在短文中解释。

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

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

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

我使用“复制”这个词。 SVN实际上并不在存储库中完整地复制这些东西。

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

分支通常用来做一些远离主干(或其他开发线)的东西,否则会破坏构建。 新的功能通常建立在一个分支,然后合并回主干。 分支通常包含未被批准用于其分支的开发线的代码。 例如,一个程序员可以尝试对某个分支进行优化,只有在优化满足后才能重新合并到开发线中。

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

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

  • 源代码管理HOWTO

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

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

这是我简单的方法,

主干 – 主干目录包含最新的,批准的和合并的工作主体。 与许多人所承认的相反,我的躯干只是干净整洁的工作,而不是一个发展领域,而是一个释放领域。

在一些特定的时间点,当主干似乎准备好释放,然后它被标记和释放。

分支 – 分支目录包含实验和正在进行的工作。 在一个分支下工作,直到被批准合并到主干。 对我来说,这是所有工作都完成的领域。

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

标签 – 标签目录包含批准的分支和中继发行的快照。 只要分支机构被批准合并到中继线中,或者释放中继线,就会在标签下创建批准的分支机构或中继线释放的快照。

我认为,通过标签,我可以通过时间跳来跳去,很容易地指出兴趣。

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

分行目录是用来存放你的分行,不管它们是什么。

标签目录基本上用于标记一组特定的文件。 你这样做是为了发布这样的东西,在这些版本中你想要“1.0”作为这些文件,在这些版本中是“1.1”作为这些文件。 一旦制作完成,您通常不会修改标签。 有关标签的更多信息,请参阅第4章。分支和合并 (在使用Subversion的版本控制中 )。

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

当我查找OpenCV 2计算机视觉应用程序编程手册的作者的网站时,我发现这个关于SVN的好教程,我想我应该分享一下。

他有一个关于如何使用SVN的教程以及短语“trunk”,“tag”和“branch”是什么意思。

直接从他的教程引用:

你的团队当前工作的软件项目的当前版本通常位于名为trunk的目录下。 随着项目的发展,开发人员会更新该版本修复bug,添加新功能),并在该目录下提交他的更改。

在任何特定的时间点,您可能需要冻结一个版本,并捕获该软件的快照,因为它处于开发的这个阶段。 这通常对应于您的软件的正式版本,例如,您将提供给您的客户的软件。 这些快照位于项目的标签目录下。

最后,在某个时候,为您的软件创建新的开发路线通常很有用。 例如,当你想测试一个替代的实现时,你必须修改你的软件,但是你不想把这些修改提交给主项目,直到你决定采用新的解决方案。 然后,主团队可以继续在项目上工作,而其他开发人员则在原型上工作。 你可以把这个新项目的开发线放在一个名为branches的目录下。

标记=一个定义的时间片,通常用于发布

我认为这是“标签”通常意味着的。 但是在Subversion中:

他们没有任何正式的意义。 文件夹是SVN的文件夹。

我觉得这很容易混淆:一个对分支或标签一无所知的版本控制系统。 从实现的角度来看,我认为Subversion创建“副本”的方式非常聪明,但是我必须知道的是我所说的抽象漏洞

或者也许我刚刚使用CVS的时间太长了。

我认为,一些混淆来自标签的概念和SVN实现之间的区别。 SVN的标签是一个分支是一个副本。 修改标签被认为是错误的,事实上,像TortoiseSVN这样的工具会在你试图修改路径中的../tags/ ..时发出警告。

我不太清楚“标记”是什么,但分支是一个相当常见的源代码控制概念。

基本上,分支是一种在不影响主干的情况下对代码进行更改的方法。 假设你想添加一个相当复杂的新功能。 您希望能够在进行更改时检查它们,但不要在完成该功能之前影响主干。

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

有许多人用于分支的模式。 如果您的产品一次支持多个主要版本,通常每个版本都是一个分支。 我在哪里工作,我们有一个质量保证部门和一个生产部门。 在将我们的代码发布到QA之前,我们将更改集成到QA分支,然后从那里进行部署。 在发布到生产时,我们将QA分支集成到生产分支,所以我们知道在生产中运行的代码与QA测试的代码是一样的。

这是维基百科在分支机构的条目 ,因为它们可能比我所能解释的更好。 🙂

中继线是应用程序代码的基础文件夹。 在这里,你在你的下一个版本/版本上工作。

分支是一个文件夹,允许你选择一个时间,并允许你走下一条不同于/ Trunk的发展道路。 分支的一个常见用途是为您的开发团队提供在生产中存在的应用程序当前快照, /分公司/生产维护。

这个“分支”的概念可以让你的团队建立修改/增强生产,而不会影响你目前正在/ Trunk中进行下一个版本的正在进行的工作。 分支也可以是小型功能,在大型团队中允许开发人员以原子方式工作,并在将来重新合并到/ Trunk中。

标签是一个文件夹,可以让你拍摄你的应用程序的快照,并使用这些特定的“构建”。 这使您的团队在测试和查找构建之间的差异方面具有灵活性。 您经常会在/ Branch中找到一个命名约定,它与您的构建相关,即。 /分支/2.0.0,/分支/2.0.1,/分支/3.1.0等等。 命名约定取决于你和你的团队。 保持一致!

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

分支 :每个正在进行的冲刺的所有平行发展代码都保存在分支中。

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

Interesting Posts