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

它们是什么意思?


当前回答

首先,正如@AndrewFinnell和@KenLiu指出的,在SVN中,目录名称本身没有任何意义——“主干、分支和标记”只是大多数存储库使用的一种常见约定。并不是所有的项目都使用所有的目录(根本不使用“标签”是很常见的),事实上,没有什么可以阻止您调用任何您想要的名称,尽管打破常规经常会令人困惑。

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

Trunk: The main development area. This is where your next major release of the code lives, and generally has all the newest features. Branches: Every time you release a major version, it gets a branch created. This allows you to do bug fixes and make a new release without having to release the newest - possibly unfinished or untested - features. Tags: Every time you release a version (final release, release candidates (RC), and betas) you make a tag for it. This gives you a point-in-time copy of the code as it was at that state, allowing you to go back and reproduce any bugs if necessary in a past version, or re-release a past version exactly as it was. Branches and tags in SVN are lightweight - on the server, it does not make a full copy of the files, just a marker saying "these files were copied at this revision" that only takes up a few bytes. With this in mind, you should never be concerned about creating a tag for any released code. As I said earlier, tags are often omitted and instead, a changelog or other document clarifies the revision number when a release is made.


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

Trunk / -开发版本,即将发布1.0 分支/ -空

一旦1.0.0完成,你将分支trunk到一个新的“1.0”分支,并创建一个“1.0.0”标记。现在,关于最终1.1版本的工作继续在主干中进行。

Trunk / -开发版本,即将发布1.1 分支/1.0 - 1.0.0发布版本 Tags /1.0.0 - 1.0.0发布版本

You come across some bugs in the code, and fix them in trunk, and then merge the fixes over to the 1.0 branch. You can also do the opposite, and fix the bugs in the 1.0 branch and then merge them back to trunk, but commonly projects stick with merging one-way only to lessen the chance of missing something. Sometimes a bug can only be fixed in 1.0 because it is obsolete in 1.1. It doesn't really matter: you only want to make sure that you don't release 1.1 with the same bugs that have been fixed in 1.0.

Trunk / -开发版本,即将发布1.1 分支/1.0——即将发布的1.0.1版本 Tags /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版 Tags /1.0.0 - 1.0.0发布版本 Tags /1.0.1 - 1.0.1发布版本

最终,你几乎准备好发布1.1,但你想先做一个测试版。在本例中,您可能会执行“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版本 Tags /1.0.0 - 1.0.0发布版本 Tags /1.0.1 - 1.0.1发布版本 Tags /1.1beta a1 - 1.1beta1发布版本

一旦发布了1.1 final版本,就可以从“1.1”分支执行“1.1”标记。

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


分支的另一个用途是用于特性。这是你分支主干(或你的发布分支之一)并独立开发新特性的地方。一旦特性完成,您将其合并并删除分支。

Trunk / -开发版本,即将发布1.2 分支/1.1——即将发布的1.1.0版本 分支/ui-rewrite -实验特性分支

The idea of this is when you're working on something disruptive (that would hold up or interfere with other people from doing their work), something experimental (that may not even make it in), or possibly just something that takes a long time (and you're afraid if it holding up a 1.2 release when you're ready to branch 1.2 from trunk), you can do it in isolation in branch. Generally you keep it up to date with trunk by merging changes into it all the time, which makes it easier to re-integrate (merge back to trunk) when you're finished.


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

其他回答

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

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

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

分支通常用于做一些远离主干(或其他开发线)的事情,否则会破坏构建。新特性通常构建在分支中,然后合并回主干中。分支通常包含一些代码,这些代码不一定被分支的开发线所批准。例如,程序员可以尝试对分支中的某些内容进行优化,只有在优化令人满意时才会合并回开发线上。

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

这里有一个链接到一个非常好的知识库指南:

源码控制

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

主干:在敏捷的每一个冲刺阶段结束后,我们会推出一个部分可交付的产品。这些释放物被保存在后备箱里。

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

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

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

Trunk is a main branch recommended by Subversion, but you are in no way forced to create it. You could call it 'main' or 'releases', or not have one at all! Branch represents a development effort. It should never be named after a resource (like 'vonc_branch') but after: a purpose 'myProject_dev' or 'myProject_Merge' a release perimeter 'myProjetc1.0_dev'or myProject2.3_Merge' or 'myProject6..2_Patch1'... Tag is a snapshot of files in order to easily get back to that state. The problem is that tag and branch is the same in Subversion. And I would definitely recommend the paranoid approach: you can use one of the access control scripts provided with Subversion to prevent anyone from doing anything but creating new copies in the tags area.

标签是最终的。其内容不应改变。从来没有。永远。你忘了发行通知里的一行字?创建一个新标记。淘汰或删除旧的。

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

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

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

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

标签=在时间上定义的片段,通常用于发布

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

它们没有任何正式的含义。文件夹对于SVN来说就是一个文件夹。

我觉得很困惑:一个对分支或标签一无所知的修订控制系统。从实现的角度来看,我认为创建“副本”的Subversion方式非常聪明,但我必须了解它,这就是我所说的有漏洞的抽象。

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