进行持续集成时的最佳分支策略?

时间:2009-02-28 07:44:15

标签: svn version-control continuous-integration branch

当您想要进行持续集成时,最佳分支策略是什么?

  1. 发布分支:在trunk上开发,为每个版本保留一个分支。
  2. 功能分支:在单独的分支中开发每个功能,只合并一次稳定。
  3. 将这两种策略结合使用是否有意义?在,你为每个版本分支,但你也分支大型功能?这些策略中的一个是否与持续集成更好地结合?使用不稳定的主干时,使用持续集成是否有意义?

12 个答案:

答案 0 :(得分:20)

答案取决于团队规模和源代码控制的质量以及合并正确复杂变更集的能力。例如,在完整的分支源控制中,如CVS或SVN合并可能很困难,使用第一个模型可能会更好,而如果使用更复杂的系统(如IBM ClearCase)和更大规模的团队,您可能会更好地使用第二个模型模型或两者的结合。

我个人会将功能分支模型分开,其中每个主要功能都是在一个单独的分支上开发的,每个变更都由各个开发人员完成。随着功能稳定,它们会合并到主干,您可以保持相当稳定并始终通过所有回归测试。当您接近发布周期结束并且所有功能分支合并时,您可以稳定并分支发布系统分支,在该分支上您只执行稳定性错误修复和必要的反向移植,而主干用于开发下一个版本,您再次使用分支新的功能分支。等等。

这种方式trunk总是包含最新的代码,但是你设法使它保持相当稳定,在主要变化和功能合并上创建稳定的标签(标签),功能分支是快节奏的开发,具有持续集成和单个任务子分支可以经常从功能分支刷新,以使每个人同步处理同一功能,同时不影响其他使用不同功能的团队。

同时,您可以通过历史记录获得一系列发布分支,您可以为您的客户提供后端,支持和错误修正,无论出于何种原因,这些客户可以使用以前版本的产品,甚至只是最新发布的版本。与主干一样,您不需要在发布分支上设置持续集成,它们在通过所有回归测试和其他发布质量控制时都会仔细集成。

如果出于某种原因,两个功能是相互依赖的并且需要相互更改,您可以考虑在同一个功能分支上开发两者,或者要求功能定期将代码的稳定部分合并到主干,然后刷新从中继线到中继线分支之间交换代码的更改。或者,如果您需要将这两个功能与其他功能隔离开来,则可以创建一个公共分支,您可以在该分支上分支这些功能分支,并且可以使用这些分支在功能之间交换代码。

上述模型没有多少意义,50个开发人员和源控制系统的团队没有稀疏的分支和适当的合并功能,如CVS或SVN,这只会使整个模型成为设置,管理和集成的噩梦。

答案 1 :(得分:20)

我认为这个话题非常有趣,因为我在日常工作中严重依赖分支机构。

  • 我记得马克·沙特尔沃思(Mark Shuttleworth)提出了一个关于保持主要分支原始而超越传统CI的模型。我发布了here
  • 由于我熟悉Cruise Control,我还在博客中介绍了任务分支和CI here。这是一个循序渐进的教程,解释了如何使用Plastic SCM
  • 最后,我在杜瓦尔关于CI very interesting too的书中找到了一些关于CI的话题(可能还有关于分支的讨论)。

希望您找到有趣的链接。

答案 2 :(得分:9)

我个人觉得拥有稳定的后备箱并进行功能分支会更加清晰。这样,测试人员等可以保持单个“版本”并从主干更新以测试任何代码完成的功能。

此外,如果多个开发人员正在开发不同的功能,他们都可以拥有自己独立的分支,然后在完成后合并到主干并发送要测试的功能,而测试人员不必切换到多个分支来测试不同的特征

作为额外的奖励,可以自动进行一定程度的集成测试。

答案 3 :(得分:5)

如果您需要维护应用程序的多个版本,发布分支非常有用,甚至是绝对必需的。

功能分支也非常方便,特别是如果一个开发人员需要处理大量更改,而其他人仍然会发布新版本。

所以使用这两种机制对我来说是一个非常好的策略。

来自Book of SVN的有趣链接。

答案 4 :(得分:5)

我认为,如果您记住每个开发人员每天提交给trunk / mainline的关键原则之一,那么这两种策略都可以用于持续开发。

http://martinfowler.com/articles/continuousIntegration.html#EveryoneCommitsToTheMainlineEveryDay

修改

我一直在阅读关于CI的this book,并且作者建议按版本分支是他们首选的分支策略。我必须同意。使用CI时,按功能分支对我没有意义。

我会试着解释为什么我这么想。假设有三个开发人员分别负责某个功能。每项功能都需要几天或几周才能完成。为确保团队不断整合,他们必须每天至少一次向主要分支机构投入使用。一旦他们开始这样做,他们就失去了创建功能分支的好处。他们的更改不再与所有其他开发人员的更改分开。既然如此,为什么还要先创建功能分支呢?

按版本使用分支需要在分支之间进行更少的合并(总是一件好事),确保所有更改尽快集成并且(如果正确完成)确保您的代码库始终准备好发布。通过发布分支的缺点是你必须更加小心改变。例如。必须逐步进行大型重构,如果您已经在下一个版本中集成了一个您不想要的新功能,则必须使用某种feature toggling机制隐藏它。

另一个编辑

关于这个问题,有不止一个意见。这是一篇博客文章,是专业分支与CI

http://jamesmckay.net/2011/07/why-does-martin-fowler-not-understand-feature-branches/

答案 5 :(得分:4)

我最近在使用git时喜欢this model。虽然您的问题被标记为“svn”,但您仍然可以使用它。

持续集成在某种程度上可以发生在这个模型中的“开发”分支(或者你称之为的任何分支)中,尽管为将来的版本提供长期运行的功能分支不会使它变得如此严格以至于不能考虑发生的每一个变化。代码在某处。问题仍然存在,你是否真的想要那样。 Martin Fowler does.

答案 6 :(得分:2)

只要您了解原则,您就可以随时重新发明最佳实践。如果您不理解原则,那么由于外部要求存在一些冲突,最佳实践将会在您崩溃之前将其带走。

有关Mainline模型的最佳介绍,请阅读:https://web.archive.org/web/20120304070315/http://oreilly.com/catalog/practicalperforce/chapter/ch07.pdf

阅读链接。一旦掌握了基础知识,请阅读以下文章,由着名的Henrik Kniberg撰写。它将帮助您将Mainline Model与持续集成联系起来。

http://www.infoq.com/articles/agile-version-control

答案 7 :(得分:2)

持续集成不应成为决定分支策略的任何因素。您的分支方法应根据您的团队,正在开发的系统以及可用的工具进行选择。

说完了......

  • 没有理由为什么CI不能用于你描述的两种方法
  • 这些方法在组合中运作良好
  • 这两个人中的任何一个都不比其他人“更好”
  • CI使用不稳定的主干完全有意义

所有这些都在您从中获取图表的页面上的第四个问题中得到了解答:http://blogs.collab.net/subversion/2007/11/branching-strat/

答案 8 :(得分:1)

当我们开始我们的团队时,我们继承了最初开发我们即将负责的系统的供应商的基于发布的策略。它一直工作到我们的客户要求一个版本中不应包含几个开发的功能(f.y.i.~250k代码行,~2500个文件,带有XP SDLC的Scrum)。

然后我们开始研究基于特征的分支。这也工作了一段时间 - 比如我们意识到我们的回归测试过程将花费超过2周,结合将要发布的不确定性,这将导致一个巨大的不便。

当我们决定我们应该拥有1.稳定的树干和2.生产应该包含ST,UAT和回归测试的BINARIES(不仅仅是源 - 想想CC)时,纯SC策略的最终“棺材中的钉子”来了。

这使我们设计出一种策略,该策略是基于特征和基于发布的SC策略的混合。

所以我们有一个主干。每个sprint我们分支sprint分支(对于非敏捷人员 - sprint只是一个时间盒开发工作,基于复杂性的可变输出。)从sprint分支我们创建功能分支并在其中开始并行开发。一旦功能完成并进行系统测试,我们就会收到部署它们的意图,它们会合并到sprint分支 - 有些可能会浮动几个sprint,通常是更复杂的sprint。一旦sprint接近尾声并且功能完成......我们将sprint分支“重命名”为“回归”(这允许CruiseControl在没有任何重新配置​​的情况下接收它)然后在cc-built上开始回归/集成测试耳。完成后,它就会投入生产。

简而言之,基于特征的分支用于开发,系统测试和UAT功能。 sprint分支(实际上是发布分支)用于有选择地按需和集成测试合并功能。

现在这是社区的一个问题 - 我们显然无法执行持续集成,因为开发发生在许多分支和CruiseControl的重新配置开销上。有人可以建议和建议吗?

答案 9 :(得分:0)

我看到它的方式你想拥有一组有限的分支,你可以集中注意力。由于您需要测试,代码质量指标以及许多与构建一起运行的有趣内容,因此报告太多可能会让您错过信息。

分支的时间和内容通常取决于团队的规模和正在开发的功能的大小。我认为没有黄金法则。确保您使用的策略可以提前/经常获得反馈,其中包括从功能的最开始就涉及到质量。质量位,意味着随着团队的发展自动化,如果您为团队正在构建的大型功能集进行分支,那么您也必须具备团队的质量。

ps你在哪里获得这些方法参考? - 不认为这些图表代表所有选项

更新1:扩展为什么我说它不是黄金法则。基本上对于相对较小的团队,我发现最好使用一种混合方法。如果功能分支很长,并且团队的一部分将继续添加较小的功能,则会创建功能分支。

答案 10 :(得分:0)

Dave FarleyContinuous Delivery的作者,称Trunk Based Development (TBD)是持续集成(CI)和持续交付(CD)的基石。他说:

  

任何形式的分支都与持续集成相反。

他还说

  

功能分支从个人开发人员的角度来看非常好,但是从团队的角度来看不是最佳的。我们都希望能够忽略其他所有人在做什么,并继续我们的工作。不幸的是,代码不是那样的。即使在结构良好的代码库中,它们也具有漂亮的关注点分离和组件之间的松散耦合,某些更改也会影响系统的其他部分。

Trunk Based Development (TBD)是每天至少一次(最好每天多次)将代码更改集成到主干(又称主,干线)中的实践。持续集成(CI)是一种类似的做法,除了它还涉及使用自动化测试来验证代码更改。最好的分支策略是直接在主干上工作,并通过Pair-Programming执行代码审查。如果由于某种原因您无法配对,或者您只想真正分支,请确保分支寿命短(少于一天)。

  

我在Trunk(我的GIT仓库)中的“ master”上工作。我承诺在本地进行管理,并在联网时立即推送到运行CI的中央主存储库。就是这样!

对于大型功能(例如,耗时超过一天的功能),请尝试将其分解为小的逻辑块,这些逻辑块可以集成到主干中而不会破坏软件。您还可以使用诸如feature-flaggingbranching by abstraction之类的技术,使您可以部署不完整的工作而不影响最终用户。

  

我通过抽象,深色发布以及有时使用特征标记来使用分支。我得到的回报是快速,确定的(至少对我的测试质量而言)反馈。

答案 11 :(得分:-3)

我认为您使用的工具是一个重要因素。

  • 如果您正在使用subversion,请坚持使用选项1并从分支中释放。
  • 如果您使用GIT,选项2将很适合您。