您是在分支机构还是在主干中继续开发?[关闭]


170

假设您正在开发具有定期发布的软件产品。关于分支和合并的最佳实践是什么?划分给公众(或您的客户是谁)的定期发布分支,然后继续在主干上进行开发,或者将主干视为稳定版本,将其定期标记为发布,然后在分支中进行实验性工作。人们认为行李箱被认为是“金”还是被认为是“沙盒”?


3
不知道是否可以在没有svn的情况下重新标记它,因为它对于源代码管理非常通用?
Scott Saad

4
这似乎是那些“宗教”问题之一。
James McMahon

@詹姆斯·麦克马洪(James McMahon)-确实有两种互斥的最佳实践,但有些人认为只有一种。SO希望您得到一个正确的答案并没有帮助。
刘坚

Answers:


151

我已经在大型商业应用中尝试了这两种方法。

哪种方法更好的答案很大程度上取决于您的实际情况,但是我将写出到目前为止我的总体经验。

总体上更好的方法(以我的经验):中继线应始终保持稳定。

这是此方法的一些准则和好处:

  • 将每个任务(或相关任务集)编码在其自己的分支中,这样您便可以灵活地合并这些任务并执行发布。
  • 在将每个分支合并到主干之前,应先对其进行质量检查。
  • 通过对每个分支进行质量检查,您将确切地知道导致该错误的原因。
  • 该解决方案可扩展到任意数量的开发人员。
  • 由于分支是SVN中几乎立即的操作,因此该方法有效。
  • 标记您执行的每个发行版。
  • 您可以开发暂时不打算发布的功能,并确定何时合并它们。
  • 对于您所做的所有工作,您都可以提交代码。如果仅在主干之外工作,则可能会使代码未提交很多,因此不受保护,并且没有自动历史记录。

如果您尝试相反的操作并在中继中进行所有开发,则会遇到以下问题:

  • 日常构建中不断出现的构建问题
  • 当一个开发人员向项目中的其他所有人提出问题时,生产力损失
  • 发行周期更长,因为您最终需要获得稳定的版本
  • 发行不稳定

如果试图保持分支稳定并且将主干作为开发沙箱,那么您将根本没有所需的灵活性。原因是您无法从中继中选择要在该稳定版本中放入的内容。它将已经全部混入树干中。

我要说的是在主干中进行所有开发的一种情况是,当您开始一个新项目时。根据您的情况,可能还会有其他情况。


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


35
抱歉,这个答案是错误的。所有开发都应在主干中进行。如果您有“尖峰”或“危险”特征,请创建一个特征分支。应该针对生产中产品的每个版本维护分支,或者如果存在单个版本,请使用Integration分支。
米奇小麦

52
我并不是说这是唯一的方法,而只是说这是更好的方法。当然,如果您认为您有足够的理由认为我错了,那么您应该发布它。至少我的回答是合理的。
Brian R. Bondy

5
这是有问题的,因为开发人员可以在与主干线分开的分支上长时间工作。稍后将这些东西集成可能会引起很大的麻烦。对我来说,始终保持最低要求的出血树干(必须始终进行编译)总是很容易,并且分支应该稳定释放的东西总是比较容易的。
Mnementh,2009年

31
在回应Mnementh的帖子时,我相信一个好的解决方案是,开发人员应定期将主干合并到其分支中,以使它们与主干的状态之间的距离不会太远。每个开发人员都应经常执行此操作,以使他们在任何时间点都不会遇到巨大的重新集成难题。
RjOllos

8
@Mnementh这不是借口。最佳实践和常识说,团队中的每个人都应该使用主干更新其分支。主线干线既不是完美的,也不是您要投入生产的东西,它只是需要编译,这就是为什么在良好的开发环境中,大多数开发人员都非常擅长确保这种情况发生,如果没有,团队有权给该人带来麻烦...还有诸如Cruise Control和其他连续构建设置之类的工具。这就是持续集成的全部意义所在!您需要对分支机构进行质量检查,而不是对主干进行质量检查。
PositiveGuy 2010年

66

我已经使用了这两种技术,我会说在主干上进行开发并在发布时分叉稳定点是最好的方法。

那些反对的人说您将拥有:

  • 日常构建中不断出现的构建问题
  • 当一个开发人员向项目中的其他所有人提出问题时,生产力损失

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

的确,如果您在一天中不执行几次测试构建,例如每小时大约进行一次,将使自己容易受到这些问题的困扰,这些问题将很快扼杀开发的步伐。

白天进行几次测试构建会迅速折叠到主要代码库的更新中,以便其他人可以使用它,并且如果有人破坏了构建,也可以在白天提醒您,以便他们可以在回家之前进行修复。

正如指出的那样,仅当夜间运行运行回归测试的构建失败时才发现损坏的构建是愚蠢的,并且会很快降低运行速度。

阅读Martin Fowler关于持续集成的论文。我们在Posix sh的大约2,000行中为大型项目(3,000kSLOC)推出了自己的此类系统。


1
“持续集成”与一个团队的功能迟到并延迟整个发布周期的可能性有什么关系?这是“为您服务”的最佳方式!每天进行几次构建并不能解决任何潜在问题,除非您知道它可以构建!您的论据没有提供证明这是更好的方法的证据(尽管我通常也是这样做的)。
Jeach 2010年

CI对于此答案是必需的,但对于Brian的回答也是如此。
jyoungdev

2
@Jeach,每天进行几次构建,​​可以使您信心十足,可以定期运行测试,无论是白天的简单smkoke测试还是晚上的回归测试。如果您将构建保留到晚上进行回归测试,则可能因为无法构建而将整个项目推迟一天。这意味着所有开发人员将无法查看他们提交的新代码的回归测试结果。仅因为,例如,某人签入了包含语法错误的代码,这是一笔非常昂贵的费用。
Rob Wells

如果一项功能需要2个月的构建时间,而另一项功能需要6个月的构建时间,您必须在那儿使用分支机构,在这种情况下并不是所有内容都可以签入主
干吗

1
@Wolf,您将混乱与混乱混淆,人们在制造产品,而不是每个人都为开发人员工作
Kalpesh Soni

36

我倾向于采用“发布分支”方法。中继线易失。一旦发布时间临近,我将创建一个发布分支,我将更加谨慎地对待它。最终完成后,我会标记/标记存储库的状态,以便知道“正式”发布的版本。

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


19

都。

主干用于大多数开发。但是,预计将尽最大努力确保对行李箱的任何登机手续都不会中断。(由自动构建和测试系统部分验证)

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

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


3
我在这方面与您同在...一直只坚持一种方法的开发人员是问题所在!
Jeach 2010年

14

我喜欢并使用Henrik Kniberg在“多个敏捷团队的版本控制”中描述的方法。Henrik在解释如何在具有多个团队的敏捷环境中处理版本控制方面做得非常出色(在传统环境中也适用于单个团队),对他的措辞毫无意义,所以我只发布“备忘单”(自我解释如下:

替代文字 替代文字

我喜欢它因为:

  • 很简单:您可以从图片中获取它。
  • 它运作良好(且可扩展),而没有太多的合并和冲突问题。
  • 您可以随时(出于敏捷的精神)发布“工作软件”。

并且,以防万一它不够明确:开发是在“工作分支”中完成的,干线用于DONE(可释放)代码。有关所有详细信息,请检查多个敏捷团队的版本控制


我的个人经验是,这仅适用于小型团队,与您的“按比例缩放”评论不同。随着团队的成长和故事的改组,所有其他团队花费大量团队进行合并。在非常大的项目(许多文件和KLOC)上,合并问题经常会开始出现,尤其是在代码波动很大的情况下。
2010年

@Jeach在一个大型项目中,它由功能团队组成的5个团队为我们工作得很好,尽管我并不否认合并是有代价的。
Pascal Thivent 2010年

11

Divmod的终极质量开发系统是保持中继线稳定并在分支机构中完成所有工作的开发过程的一个很好的参考。快速总结:

  • 完成的所有工作都必须具有相关联的票证
  • 为每个故障单完成工作的地方创建一个新的分支
  • 来自该分支的更改不会重新合并到主干干线中,而无需其他项目成员的审查

他们为此使用SVN,但是可以使用任何分布式版本控制系统轻松完成此操作。


10

我认为您的第二种方法(例如,考虑发行版的稳定性,在分支中对版本进行标记并进行实验)是最好的方法。

应当清楚的是,分支机构在分支机构的时间点继承了系统的所有错误:如果将修补程序应用于主干,则如果您将分支机构维护为某种形式,则必须逐一遍历所有分支机构。释放周期终止符。如果您已经有20个发行版,并且发现了一个可以追溯到第一个版本的错误,则必须重新应用此修复程序20次。

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


8

除非更改过于重大,不稳定或我们即将推出其中一种产品,否则我们将在主干上进行开发,在这种情况下,我们将创建一个临时分支。我们还为每个单独的产品版本创建一个永久分支。我在以下位置找到了Microsoft的文档分支指导》很有帮助。埃里克·辛克(Eric Sink)的分支教程也很有趣,并指出,对于Microsoft而言,对我们中的某些人来说可能过于沉重。就我们而言,我们实际上使用了Eric的团队所说的方法。


5

这取决于您的情况。我们使用Perforce,通常会有几条开发线。主干被认为是“黄金”,并且所有开发都发生在分支机构,只要它们足够稳定可以集成,它们就会合并回到主线。这样就可以拒绝那些无法完成的功能,并且可以随着时间的推移提供可靠的增量功能,以便独立项目/功能可以使用。

合并和追赶引入后备箱的新功能会产生集成成本,但是无论如何您都会遭受这种痛苦。每个人都在主干上共同发展会导致荒唐的西部局势,而分支机构则使您可以扩展规模并选择要采取苦涩整合方案的地步。目前,我们的规模已扩展到十几个项目的一百多个开发人员,每个项目使用相同的核心组件发布多个版本,并且运行良好。

这样做的好处是您可以递归执行此操作:大功能分支可以是其自己的主干,其他分支也可以退出。此外,最终版本会获得一个新分支,为您提供进行稳定维护的地方。


4

尝试根据新开发来管理当前生产代码的维护充其量是有问题的。为了减轻这些问题,一旦完成测试工作并且准备好交付代码,则代码应分支到维护行中。此外,主线应分支以帮助稳定发行,遏制实验性开发工作或容纳其生命周期跨越多个发行版的任何开发工作。

仅当代码之间存在冲突(或确定性)而很难以其他任何方式管理时,才应创建非维护分支。如果分支机构不能解决后勤问题,它将创建一个。

正常发布开发发生在主线中。开发人员签入和签出主线以进行正常发布工作。当前生产代码补丁的开发工作应该在该版本的分支中,一旦补丁通过测试并部署,便与主线合并。非维护部门的工作应根据具体情况进行协调。


4

这取决于您的开发工作量。多个并行工作的团队将无法在同一代码(全部)上有效地工作。如果您只有一小群人在工作,而您的主要关注点是削减分支机构,那么您可以继续工作,同时返回分支机构,以对当前有效的生产代码进行错误修复。这是分支的琐碎用途,并且不太麻烦。

如果您有很多并行开发,则需要为每个工作都创建分支,但这还需要更多的纪律:确保分支经过测试并准备好合并。计划合并,因此两个组不会尝试同时合并等。

某些分支的开发已经持续了很长时间,您必须允许从主干到分支的合并,以减少最终合并回主干时的意外情况。

如果您有大量的开发人员,则必须进行试验,并了解在您所处的环境中什么可行。这是来自Microsoft的页面,该页面可能会有些有用:http : //msdn.microsoft.com/zh-cn/library/aa730834(VS.80).aspx


4

我们使用主干进行主要开发,并使用分支进行发布维护工作。很好用 但是分支应该只用于错误修复,而不能进行大的更改,尤其是在数据库方面,我们有一个规则,即只能在主干上进行模式更改,而不能在分支中进行更改。


1
为什么分支中没有数据库的规则会更改?
比约恩·雷彭

我们只有一条规则,因为它使我们的数据库版本合并更加容易。那可能是因为我们使用脚本文件名中的排序来更新数据库的方式,我确定如果有其他方法,可以在分支上进行数据库更改。
adriaanp

2

如果您要经历发布周期的重大功能,那么您将陷入困境。否则,我们将在主干中工作,并在构建时针对每个生产版本进行分支。

以前的生产版本当时已移至old_production_,而当前的产品发布始终只是生产。我们所有的构建服务器都知道生产是如何部署生产分支,并且我们通过强制触发来开始构建。


2

我们遵循主干=当前的开发流,分支=版本的方法。在向客户发布时,我们会分支树干,并保持树干向前滚动。您需要确定准备支持多少个版本。您支持的越多,您将在错误修复方面进行的合并就越多。我们尝试让客户在主干之后最多发布2个版本。(例如Dev = 1.3,受支持的版本1.2和1.1)。


1

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

发布是分支的,通常是在分支上进行实验或主要工作,然后在准备与主开发线集成时又合并回主干。


1

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

我们将发布的产品贴上标签,以便我们能够快速应对生产紧急情况,而不会影响积极的开发。


1

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

在CVS下,我只会工作在“ trunk”中,而不会标记/分支,因为否则确实很痛苦。

在SVN中,我会在中继中执行“出血边缘”操作,但是当需要进行服务器推送时,将对其进行适当标记。

我最近切换到git。现在我发现我从不在后备箱里工作。相反,我使用一个名为“ new-featurename”的沙箱分支,然后合并到一个固定的“当前生产”分支中。现在,我考虑了一下,在合并回“当前生产版本”之前,我确实应该制作“ release-VERSIONNUMBER”分支,以便可以返回到较旧的稳定版本。


1

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

  • 如果可以轻松计划下一个版本(在下一个版本中),那么最好在主干中进行开发。管理分支机构需要更多的时间和资源。但是,如果不能轻松地计划下一个计划(在大型组织中一直都在发生),那么您可能最终会选择樱桃采摘(数百/千)而不是分支(数或数十)。
  • 使用Git或Mercurial,管理分支比cvs和Subversion容易得多。我会选择稳定的主干/主题分支方法。这就是git.git团队使用的。阅读:http : //www.kernel.org/pub/software/scm/git/docs/gitworkflows.html
  • 通过Subversion,我首先应用了开发中的方法。关于发布日期,有很多工作要做,因为每次我不得不挑选提交时(我的公司不擅长计划)。现在,我是Subversion的专家,并且对Subversion的分支管理非常了解,因此我正在朝着稳定的主干/主题分支方法发展。它比以前更好。现在我正在尝试git.git团队的工作方式,尽管我们可能会坚持使用Subversion。

1

这是我更喜欢的SVN设计:

    • 发展
      • 分行
        • 功能1
        • 功能2
        • ...
      • 树干
    • 贝塔
      • 标签
      • 树干
    • 释放
      • 标签
      • 树干

除了需要自己分支的主要功能以外,所有工作都是通过开发/主体完成的。在针对开发/树干测试工作之后,我们将经过测试的问题合并到Beta /树干中。如有必要,将针对Beta服务器测试代码。当我们准备好进行一些更改时,我们只需将适当的修订合并到发行版/主体中并进行部署。

可以在beta分支或release分支中进行标记,因此我们可以跟踪beta和release的特定版本。

这种设计具有很大的灵活性。如果某些修订未通过Beta中的测试,这也使我们可以轻松地保留beta / trunk中的修订,而将其他修订合并到release / trunk中。


0

我们使用的方法是Perforce方法,Laura Wingerd的著作中对此进行了详尽的讨论:

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

尽管本书以perforce为中心(Wingerd是Perforce产品经理),但是这些概念可以应用于任何或所有VCS。

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

这本书非常值得一读。



0

颠覆惯例问题恕我直言,没有一个万能的答案。

这实际上取决于项目和使用它的公司的动态。在快节奏的环境中,当发行可能每隔几天发生一次时,如果您认真地标记和分支,最终将导致无法管理的存储库。在这样的环境中,需要时分支的方法将创建一个更加可维护的环境。

同样-从我的经验来看,从纯粹的管理角度来看,在您选择的时候在svn方法之间进行切换非常容易。

我知道最有效的两种方法是需要时进行分支和每个任务进行分支。当然,这些是彼此完全相反的。就像我说的-一切都与项目动态有关。


-1

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

质量检查部门参与质量检查后,为每个在建分支机构提供一个安装的工作量实在太高了。考虑一下SOA /客户端/服务器/ Web服务/数据库每个分支都必须提供所有这些。

该解决方案也缺少集成阶段。


我们的团队中有几项质量检查。他们会在合并之前从分支机构构建的完整安装程序中测试每个功能。
Brian R. Bondy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.