2008-08-30 47 views
172

假设您正在开发定期发布的软件产品。关于分支和合并的最佳做法是什么?定期向公众发布分支机构(或者你的客户),然后继续开发主干,或者考虑将主干版本作为稳定版本,定期将其标记为发布版本,并在分支机构中进行实验性工作。人们认为树干被认为是“黄金”还是被认为是“沙箱”?你是继续在树枝上还是在树干里开发?

+3

想知道如果没有svn可以重新绑定它,因为它对于源代码控制管理是相当通用的? – 2008-09-17 03:41:04

+4

这似乎是那些“宗教”问题之一。 – 2009-01-06 16:07:01

+0

@詹姆斯麦克马洪 - 实际上有两种互斥的最佳做法,但有些人认为只有一种。它不能帮助你想要你有一个正确的答案。 – 2010-02-22 19:38:38

回答

148

我曾尝试与大型商业应用这两种方法。

答案哪种方法更好高度依赖于您的具体情况,但我会写什么我的整体体验迄今所示。

更好的方法整体(在我的经验):主干应该始终保持稳定。

下面是这种方法的一些指导和好处:

  • 代码每个任务(或相关的任务集)在自己的分公司,那么你将有灵活性,当你想合并这些任务并执行发布。
  • QA应在每个分支之前被合并到主干完成。
  • 通过对每个单独的分支做QA,你就会知道到底是什么导致了这个bug更容易。
  • 该解决方案适用于任何数量的开发人员。
  • 此方法可行,因为分支在SVN中几乎是即时操作。
  • 标记您执行的每个版本。
  • 您可以开发你不打算释放了一段时间,准确地确定何时将它们合并功能。
  • 对于您所做的所有工作,您可以享受提交代码的好处。如果您仅使用主干,则可能会使您的代码很长时间没有提交,因此无法保护,也没有自动历史记录。

如果你尝试做相反,做在树干所有的发展你有以下问题:

  • 恒建问题的每日构建
  • 生产力损失时AA开发商承诺项目上所有其他人的问题
  • 更长的发布周期,因为您需要最终获得稳定版本
  • 不太稳定的版本

如果您试图保持分支稳定,并将干线作为开发沙箱,您将不具备所需的灵活性。原因是你不能从主干中选择你想要在稳定版本中放置什么。它已经全部混在一起了。

特别是我要说的一件事情,那就是在开始一个新项目时,要在干线中进行所有开发。根据您的情况,可能还有其他情况。


顺便说一下,分布式版本控制系统提供了更多的灵活性,我强烈建议切换到hg或git。

+35

对不起,这个回答是错误的。所有的发展都应该发生在后备箱中。如果您有某些“尖峰”或某种“风险”功能,请创建一个功能分支。生产中每个版本的产品都应该维护分支,或者如果有一个版本使用集成分支。 – 2008-09-28 06:56:59

+50

我并没有声称这是唯一的方法,只是它是更好的方法。当然,如果你认为你有足够的理由认为我错了,那么你应该发布它。至少我的回答是有道理的。 – 2008-09-28 13:30:36

+2

DB方法的这种方法只有一个问题。添加到分支的合并到生产数据库中并在生产数据库上执行的SQL迁移脚本必须按创建顺序执行。功能分支有什么困难。 – 2009-08-27 10:17:12

2

干线通常是主要的开发线。

版本被分支出去,通常在分支上完成实验或主要工作,然后在准备与主要开发线集成时重新合并回主干。

36

我倾向于采取“发布分支”的方法。干线是不稳定的。一旦发布时间临近,我会创建一个发布分支,我会更仔细地对待它。当最后完成时,我会标记/标记存储库的状态,以便知道“官方”发布的版本。

我知道还有其他方法可以做到这一点 - 这是我过去做过的。

10

我认为你的第二种方法(例如,标记版本和在分支中做实验性的东西,考虑到干线稳定性)是最好的方法。

应该清楚的是,分支机构在分支时继承了系统的所有错误:如果修补程序应用于中继线,如果您维护分支机构,则必须逐个去所有分支机构作为一种释放周期终止符。如果您已经有20个版本,并且您发现了一个可以追溯到第一个版本的错误,那么您将不得不重新应用您的修补程序20次。

分支应该是真正的沙盒,尽管干线也必须扮演这个角色:标签会指示代码在该时间点是否为“黄金”,适合发布。

2

树干通常应该是您的主要开发源。否则,您将花费大量时间合并新功能。我看到它以其他方式完成,通常会导致很多最后一刻的集成问题。

我们将发布的标签贴上标签,以便我们可以快速响应生产紧急情况而不会分发活跃的开发。

8

我们在主干上进行开发,除非这些变化太重大,不稳定,或者我们正在接近我们产品的主要版本,在这种情况下,我们会创建一个临时分支。我们还为每个单独的产品版本创建一个永久分支。我发现微软的文档Branching Guidance相当有帮助。 Eric Sink的tutorial on branching也很有趣,并指出微软可能对我们其他人来说过于沉重。在我们的案例中,我们实际上使用了Eric所说的他的团队所采用的方法。

4

试图管理与新开发一致的当前生产代码的维护问题充其量就是问题。为了减轻这些问题,一旦测试工作完成并且代码准备好交付,代码应该分入维护线。另外,主线应该分支以协助释放稳定,包含试验开发工作,或者容纳生命周期延伸到多个版本的任何开发工作。

只有在代码之间存在碰撞的可能性(或确定性)时,才应该创建非维护分支,否则难以以其他方式进行管理。如果分支机构不解决后勤问题,它将创建一个。

正常版本开发发生在主线上。开发人员检查进出正常发布工作的主线。针对当前生产代码的修补程序的开发工作应该位于该发行版的分支中,并在修补程序通过测试并部署后与主线合并。非维护分支机构的工作应根据具体情况进行协调。

1

对我来说,这取决于我使用的软件。

在CVS下,我只会在“trunk”中工作,并且从不标记/分支,因为这样做非常痛苦。

在SVN中,我会在trunk中执行我的“流血边缘”的东西,但是当它是做服务器推送的时候,要适当地标记。

我最近切换到git。现在我发现我从来没有在后备箱工作。相反,我使用一个名为“新功能名称”的沙箱分支,然后合并成一个固定的“当前生产”分支。现在我想到了,我真的应该制作“release-VERSIONNUMBER”分支,然后再合并到“当前制作”中,这样​​我就可以回到较旧的稳定版本...

5

这取决于您的情况。我们使用Perforce,通常有几个开发线。干线被认为是“黄金”,所有的发展发生在分支上,当它们足够稳定以便整合时,它们被合并回主线。这允许拒绝不切割的特征,并且随着时间的推移可以提供独立的项目/特征可以获得的稳定的增量能力。

融合和追赶到树干中的新功能的整合成本,但你会遭受这种痛苦无论如何。让每个人都在躯干上一起发展可能会导致一种狂野的西方情况,而分支可以让你缩放并选择你想要服用苦药的点数。目前,我们已经将十多个开发人员扩展到了一百多个开发人员,每个开发人员都使用相同的核心组件进行多个版本的开发,并且工作得很好。

这样做的好处是你可以递归地做到这一点:一个大功能分支可以是自己的树干,如果它与其他分支脱落。此外,最终版本会获得一个新分支,为您提供一个稳定维护的地方。

2

如果你要完成一个发布周期,大功能,你会被困在一个分支。否则,我们在树干中工作,并在我们构建的时刻为每个生产版本分支。

以前的生产版本当时被移动到old_production_,并且当前版本始终只是生产版本。我们所有的构建服务器都知道生产是如何部署生产分支的,我们用强制触发器来启动生成。

4

这取决于您的开发工作量。并行工作的多个团队将无法有效地使用相同的代码(中继)。如果你只有一小部分人在工作,并且你的主要担心是切割一个分支,那么你可以继续工作,同时回到分支去修正当前生产代码的错误。这是分支的一个简单的使用,不是太繁重。

如果你有很多并行开发,你会想为每个努力都有分支,但是这也需要更多的纪律:确保你的分支经过测试并准备好合并回来。调度合并,所以两个组不会尝试同时合并等。

有些分支正在开发中,所以您必须允许从主干到分支进行合并,以便在最终合并回主干时减少意外数量。

如果你有一大群开发人员,并且了解你的情况有效,你将不得不进行实验。下面是微软的一个页面,可能是有点用处:http://msdn.microsoft.com/en-us/library/aa730834(VS.80).aspx

68

我已经同时使用了这两种技术,我会说在干线上发展并将稳定点作为发布分支是最好的方法。

那些人以上谁反对说,你必须:

  • 恒建问题的每日构建
  • 生产力损失时AA开发商提交一个问题,所有 其他人对项目

可能没有使用过持续集成技术。

确实,如果你不在白天进行多次测试,每隔一小时说一次,就会对这些问题置之不理,而这些问题很快就会扼杀开发的步伐。

在白天快速完成多个测试版本,可以在主代码库的更新中进行折叠,这样其他人就可以使用它,并且还可以在白天警告您是否有人破坏了构建,以便他们在回家之前修复它。如前所述,只有在夜间构建运行回归测试失败时发现破损构建失败纯属愚蠢,并会迅速减慢速度。

阅读Martin Fowler关于Continuous Integration的论文。我们用大约2000行Posix sh将我们自己的这种系统推广到一个重大项目(3,000kSLOC)。

3

我们遵循trunk =当前开发流,branch = release(s)方法。在发布给客户时,我们将树干分支并保持树干向前滚动。您需要决定您准备支持多少个版本。您支持的越多,您将在错误修复方面进行更多合并。我们试着让我们的客户在主干后面保留不超过2个版本。 (例如Dev = 1.3,支持版本1.2和1.1)。

11

一个关于保持树干稳定并且在分支机构都能正常工作的开发过程的很好的参考是Divmod的Ultimate Quality Development System。简要总结:

  • 做必须有一个
  • 对于其中为票工作完成
  • 从该分支的更改不会合并回每张票是创建一个新的分支相关联票的所有工作为不被其他项目成员

所评论的主线树干他们使用SVN这一点,但是这可能很容易地与任何分布式版本控制系统来完成。

0

@Brian R. Bondy:请注意,一旦您的团队达到了在项目中并行处理的一定数量的ppl /任务,这不是一个解决方案。

一旦QA部门参与QA,每个分支进行一次安装所需的工作量就太高了。认为SOA /客户端/服务器/ Web服务/数据库所有必须提供每个分支

该解决方案缺乏整合阶段。

5

我们使用主干进行主开发,分支进行版本维护工作。它工作很好。但是之后的分支只能用于bug修复,没有什么重大变化,特别是在数据库方面,我们有一条规则,只有主干上可以发生模式变化,而不会发生在分支上。

20

两者。

干线用于大多数的发展。但预计将尽最大努力确保对主干的任何入住手续不会打破。 (通过自动构建和测试系统进行部分验证)

版本保留在其自己的目录中,只对其进行了错误修复(然后合并到主干)。

任何将使主干处于不稳定或非工作状态的新功能都会在其自己的单独分支中完成,然后在完成时合并到主干中。

0

我们使用的方法是Perforce的方法,这是在长度劳拉Wingerd的伟大的书讨论:

http://oreilly.com/catalog/9780596101855/index.html

虽然这本书是Perforce的中心(Wingerd是Perforce公司产品经理),概念可以应用于任何或所有VCS。

perforce方法(和平台)为我们提供了很好的服务。它在很多公司都用过(谷歌,Intuit,我听说过,微软Windows本身)。

这本书很值得一读。

0

有没有一个放之四海而皆准的所有答案颠覆惯例的问题恕我直言。

这确实取决于项目和公司使用它的动态。在一个非常快节奏的环境中,当每隔几天发布一次发布时,如果您试图虔诚地标记和分支,最终会得到难以管理的存储库。在这样的环境中,分支机构何时需要的方法会创建更加可维护的环境。

此外 - 根据我的经验,从纯粹的管理角度来看,在您选择时可以在svn方法之间切换,非常容易。

我已经知道最好的两种方法是分支时需要的,分支每个任务。这些当然是彼此完全相反的。就像我说的 - 这完全是关于项目动态。

1

这实际上取决于您的组织/团队管理版本以及您使用的SCM的程度。

  • 如果下一步(在下一个版本中)可以很容易地计划,你最好在后备箱中开发。管理分支需要更多时间和资源。但是如果下一步不能很容易地规划(在大型组织中一直发生),你可能会选择樱桃提交(数百/数千)而不是分支(几十或几十)。
  • 使用Git或Mercurial,管理分支比CVS和颠覆更容易。我会选择稳定的主干/主题分支机构方法。这是git.git团队使用的。阅读:http://www.kernel.org/pub/software/scm/git/docs/gitworkflows.html
  • 在Subversion中,我首先应用了trunk-in-the-trunk methodlogy。在发布日期方面有相当多的工作,因为每次我必须选择提交(我的公司不擅长计划)。现在我是Subversion的专家,对Subversion中的管理分支非常了解,所以我正在朝着稳定的中继/主题分支方法发展。它比以前好得多。现在我正在尝试git.git团队的工作方式,尽管我们可能会坚持使用Subversion。
14

我喜欢并使用Henrik Kniberg在Version Control for Multiple Agile Teams中描述的方法。 Henrik在解释方面做得非常出色,如何在多个团队的敏捷环境中处理版本控制(在传统环境中也适用于单个团队),并且没有必要对他进行解释,因此我只需发布“备忘单” (这是自解释)如下:

alt text alt text

我喜欢它,因为:

  • 这很简单:你从图片中可以得到它。
  • 它工作(和规模)很好,没有太多的合并和冲突的麻烦。
  • 您可以随时发布“工作软件”(本着敏捷的精神)。

以防万一它不够明确:开发工作在“工作分支”中完成,干线用于完成(可释放)代码。查询Version Control for Multiple Agile Teams的所有细节。

1

这里是SVN的设计,我更喜欢:

    • 发展
      • 分支
        • 特征1
        • 特点2
        • ...
      • 干线
    • 测试
      • 标签
      • 干线
    • 发布
      • 标签
      • 干线

所有的工作都从开发/躯干完成,除了要求自己的分公司主要特征。在对开发/主干进行测试后,我们将测试的问题合并到beta/trunk中。如有必要,代码将针对测试版服务器进行测试。当我们准备推出一些更改时,我们只需将适当的修订合并到release/trunk和deploy中。

标签可以在beta分支或发布分支中制作,因此我们可以跟踪beta和release的特定发布。

该设计考虑了很多灵活性。如果某些修订版未通过beta测试,它还使我们可以轻松地在beta/trunk版本中保留修订版,同时合并其他版本以释放/ trunk。