103

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

  1. 发布分支:在主干上开发,为每个发布保留一个分支。
  2. 功能分支:在单独的分支中开发每个功能,仅在稳定后合并。

将这两种策略一起使用是否有意义?例如,您为每个版本分支,但您也为大型功能分支?这些策略之一是否更适合持续集成?当使用不稳定的主干时,使用持续集成是否有意义?

4

12 回答 12

21

我发现这个话题真的很有趣,因为我在日常工作中严重依赖分支机构。

  • 我记得 Mark Shuttleworth 提出了一个模型,即在超越传统 CI 的同时保持主分支的原始状态。我在这里发布了它。
  • 由于我熟悉 Cruise Control,因此我还在这里写了有关任务分支和 CI博客。这是一个分步教程,解释了如何使用Plastic SCM进行操作。
  • 最后,我在 Duvall 关于 CI 的书中发现了一些关于 CI(以及可能谈论分支)的主题也非常有趣

希望您发现这些链接很有趣。

于 2009-03-17T23:26:27.510 回答
20

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

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

这种方式主干始终包含最新的代码,但您设法保持它相当稳定,在重大更改和功能合并上创建稳定的标签(标签),功能分支是快速开发的持续集成,并且单个任务子分支可以经常从功能分支刷新,以使每个人都在同步处理相同的功能,同时不影响其他团队处理不同的功能。

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

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

上述模型对于 50 人以下的开发人员和没有稀疏分支和适当合并能力(如 CVS 或 SVN)的源代码控制系统没有多大意义,这只会使整个模型成为设置、管理和集成的噩梦。

于 2009-03-03T06:28:12.480 回答
9

我个人觉得拥有一个稳定的主干并进行功能分支要干净得多。这样,测试人员和类似人员就可以停留在一个“版本”上并从主干更新以测试代码完整的任何功能。

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

作为一个额外的好处,有一定程度的自动集成测试。

于 2009-02-28T07:50:14.667 回答
5

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

功能分支也非常方便,特别是如果一个开发人员需要进行巨大的更改,而其他人仍在发布新版本。

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

来自SVN 书的有趣链接。

于 2010-03-21T07:17:47.543 回答
5

我认为这两种策略都可以用于持续开发,只要您记住每个开发人员每天都致力于主干/主线的关键原则之一。

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

编辑

我一直在阅读这本关于 CI 的书,作者建议按发布进行分支是他们首选的分支策略。我不得不同意。使用 CI 时,按功能分支对我来说毫无意义。

我会试着解释为什么我会这样想。假设三个开发人员每个人都有一个分支来开发一个功能。每个功能都需要几天或几周才能完成。为了确保团队持续集成,他们必须每天至少提交一次主分支。一旦他们开始这样做,他们就会失去创建功能分支的好处。他们的更改不再与所有其他开发人员的更改分开。既然如此,何必一开始就创建特征分支呢?

使用发布分支需要更少的分支之间的合并(总是一件好事),确保所有更改尽快集成并且(如果正确完成)确保您的代码库始终准备好发布。按版本分支的不利方面是您必须对更改更加小心。例如,大型重构必须逐步完成,如果您已经集成了下一个版本中不需要的新功能,那么必须使用某种功能切换机制将其隐藏。

另一个编辑

关于这个问题有不止一种意见。这是一篇关于使用 CI 进行专业功能分支的博客文章

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

于 2011-06-27T21:32:48.993 回答
4

我最近在使用 git 时喜欢上了这个模型。尽管您的问题被标记为“svn”,但您仍然可以使用它。

持续集成在某种程度上可以发生在该模型的“开发”分支(或任何你称之为的分支)中,尽管为未来的版本提供长期运行的功能分支不会使它变得如此僵硬,以至于考虑到某处代码发生的每一个变化。问题仍然存在,你是否真的想要那样。马丁·福勒做到了。

于 2010-03-21T07:36:17.660 回答
2

只要你理解原则,你总是可以重新发明最佳实践。如果您不了解原则,那么最佳实践将使您在由于某些相互冲突的外部要求而崩溃之前走得那么远。

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

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

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

于 2009-04-15T23:49:36.613 回答
2

持续集成不应成为确定分支策略的任何因素。您的分支方法应根据您的团队、正在开发的系统和您可用的工具来选择。

话说回来 ...

  • 没有理由不能在您描述的两种方法中使用 CI
  • 这些方法结合起来效果很好
  • 两者都没有比另一个“更好”
  • CI 对不稳定的主干完全有意义

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

于 2010-03-21T07:34:20.643 回答
1

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

然后我们开始研究基于特征的分支。这也工作了一段时间——比如 2 个月,直到我们意识到我们的回归测试过程将花费 2 多周的时间,再加上将发布的内容的不确定性,造成了巨大的不便。

当我们决定我们应该拥有 1. 稳定的主干和 2. 生产应该包含 ST、UAT 和回归测试的二进制文件(不仅仅是源 - 想想 CC。)

这导致我们设计了一种混合了功能和基于发布的 SC 策略的策略。

所以我们有一个后备箱。每个 sprint 我们都会分支出 sprint 分支(对于非敏捷的人 - 一个 sprint 只是一个有时间限制的开发工作,具有基于复杂性的可变输出。)从 sprint 分支我们创建功能分支并在其中开始并行开发。一旦功能完成并经过系统测试,并且我们收到部署它们的意图,它们就会被合并到 sprint 分支 - 有些可能会跨越多个 sprint,通常是更复杂的。一旦 sprint 接近尾声并且功能完成......我们将 sprint 分支“重命名”为“regression”(这允许 CruiseControl 无需任何重新配置​​即可拾取它),然后在 cc-built 上开始回归/集成测试耳朵。当这一切都完成后,它就会投入生产。

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

现在向社区提出一个问题——我们显然在执行持续集成时遇到了麻烦,因为开发发生在许多分支上以及 CruiseControl 的重新配置开销。有人可以建议和建议吗?

于 2011-06-22T02:17:25.227 回答
1

持续交付的作者Dave Farley基于主干的开发 (TBD)称为持续集成 (CI) 和持续交付 (CD) 的基石。他说:

任何形式的分支都是与持续集成对立的。

他还说,

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

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

我在 Trunk 上工作,我的 GIT 存储库中的“大师”。我承诺在本地掌握并在联网时立即推送到运行 CI 的中央主存储库。而已!

对于大型功能(即需要超过一天时间的功能),请尝试将它们分解成小的逻辑块,这些逻辑块可以集成到主干中而不会破坏软件。您还可以使用特征标记抽象分支等技术,这些技术允许您在不影响最终用户的情况下部署不完整的工作。

我通过抽象、暗释放和有时特征标志使用分支。我得到的回报是快速、明确的(至少对我的测试质量而言)反馈。

于 2019-03-22T01:29:59.907 回答
0

在我看来,您希望拥有一组有限的分支,您可以集中精力。由于您想要测试、代码质量指标和许多有趣的东西与构建一起运行,因此拥有太多报告可能会让您错过信息。

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

ps 你从哪里得到这些方法参考?- 不觉得这些图表代表所有选项

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

于 2009-02-28T08:01:06.013 回答
-3

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

  • 如果您使用的是颠覆,请坚持选项 1 并从分支发布。
  • 如果您使用的是 GIT,则选项 2 对您很有效。
于 2014-04-01T13:28:09.503 回答