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


100

要进行持续集成时,最好使用哪种分支策略?

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

同时使用这两种策略是否有意义?如您所言,您为每个版本都分支了,但同时也为大型功能而分支了?这些策略之一与持续集成是否更好地结合?使用不稳定的中继线时,使用连续集成甚至有意义吗?


2
旁注:有些人会争辩说,即使添加了新功能,一切也应该始终稳定。另一方面,这可能有些理想化。
基思·品森

Answers:


21

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

  • 我记得马克·沙特尔沃思(Mark Shuttleworth)提出了一个模型,该模型可以在不超出常规CI的情况下保持主分支的原始状态。我在这里贴了一下
  • 由于我熟悉Cruise Control,因此我也在此处博客了有关任务分支和CI的博客。这是一个分步教程,介绍了如何使用Plastic SCM进行操作
  • 最后,我在Duvall的CI书中发现了一些关于CI的主题(并可能谈论分支),这些话题也非常有趣

希望您找到有趣的链接。


我们增加了对Bamboo的支持,以便按任务codicesoftware.blogspot.com/2012/02/…进行分支,并且看来他们的最新版本将通过多种版本控件(包括dvcs)以本机方式完成此任务。
pablo 2012年

20

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

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

这样,主干始终包含最新的代码,但是您可以设法使其保持合理的稳定性,在主要更改和功能合并时创建稳定的标签(标签),功能分支可以通过持续集成来快速进行开发,并且经常可以使用单个任务子分支从功能分支刷新,以使每个人都在同一个功能上保持同步,同时又不影响其他团队在使用不同的功能。

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

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

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


5
我不确定是否同意您所描述的内容对50个以下开发人员的团队没有意义。我也可以从较小的团队中受益。+1
Aardvark

2
当然,任何规模的团队都可以从中受益。问题是,在什么规模的团队中,收益要大于与繁重的流程相关的成本。
吉里·克鲁达

这类似于GitFlow和/或GitHubFlow模型。我认为这些模型不会促进持续集成(CI)。我认为,基于主干的开发是对这些模型的重大改进。
亚尼(Yani)

您可以看到此注释实际上早于git flow的原始版本。不太清楚“更好”的意思。我支持由1,5、25、150、1,000和20,000个开发人员组成的团队,他们在一定程度上整合了项目。要求各不相同,“更好”是相对的术语。您是否需要向后移植代码?安全修复程序?如果没有,那么你的生活很简单。SaaS是基于主干的开发施加的限制的直接结果。功能标志与功能分支一样复杂。除非您仅在客户排列中断时才从客户那里找出来。
吉里·克鲁达

9

我个人发现,拥有稳定的主干并进行分支功能会更加干净。这样,测试人员之类的人就可以停留在单个“版本”上,并从主干进行更新以测试代码已完成的任何功能。

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

另外,自动进行某种级别的集成测试。


另外,您是否仍在分支和标记每个主要版本?还是只是标签?
KingNestor

1
只要要素分支按照一定的规则合并到主干中,以免损坏构建,它就可以与CI一起很好地工作。我为每个生产版本进行分支和标记,这些版本仅用于错误修复。可以立即将其合并到稳定的中继中。
阿德南

@king我会说,这可能取决于您所说的主要版本,但是无论哪种情况,您都可以标记,然后在需要时分支(基于标记:))
eglasius

5

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

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

编辑

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

我将尝试解释为什么我会这样想。假设有3个开发人员各自在一个分支上从事某项功能。每个功能将需要几天或几周才能完成。为了确保团队不断整合,他们必须至少每天一次向主分支提交承诺。他们一开始这样做就失去了创建功能分支的好处。他们的更改不再与其他所有开发人员的更改分开。既然如此,为什么首先要创建特征分支呢?

通过发布使用分支需要更少的分支之间的合并(总是一件好事),确保所有更改都尽快集成,并且(如果正确完成的话)确保您的代码库随时可以发布。通过发布进行分支的不利方面是您必须更加谨慎地进行更改。例如,大型重构必须以增量方式完成,如果您已经集成了新版本中不希望使用的新功能,则必须使用某种功能切换机制将其隐藏。

另一个编辑

关于这个问题有不止一种意见。这是一篇博客文章,其中介绍了CI的专业功能

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


有趣,找不到此帖子了。
Jirong Hu

5

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

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

因此,对我而言,同时使用这两种机制是一个非常好的策略。

SVN书中有趣的链接。


4

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

持续集成在某种程度上可以在此模型的“开发”分支(或您所谓的任何分支)中进行,尽管为将来的发行版而运行的功能分支长期运行不会使它变得如此僵硬,以至于无法考虑到某处代码发生的每一次更改。问题仍然存在,您是否真的想要那个。马丁·福勒做到了。


2

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

话说回来 ...

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

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


2

只要您了解了原理,就可以始终重新发明最佳实践。如果您不了解原则,那么最佳实践将带您走得那么远,因为外部需求相互冲突。

有关主线模型的最佳介绍,请阅读以下内容: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


奥赖利章不再访问
贾森小号

1

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

然后,我们开始研究基于功能的分支。这也持续了一段时间-大约2个月,直到我们意识到我们的回归测试过程将花费2周以上的时间,再加上发布内容的不确定性,带来了极大的不便。

当我们决定拥有1.稳定的主干和2.生产应包含ST,UAT和经过回归测试的Binaries(不仅仅是来源-认为CC)时,纯SC战略的最后“钉子”出现了。

这导致我们设计出一种策略,该策略是基于功能和基于发布的SC策略之间的混合体。

所以我们有一个行李箱。我们将每个sprint分支到sprint分支(对于非敏捷人员-sprint只是一个有时间限制的开发工作,并会根据复杂性而产生可变的输出。)从sprint分支中,我们创建功能分支,并在其中开始并行开发。一旦功能完成并经过系统测试,并且我们打算部署它们,它们就会合并到sprint分支中-一些可能会跨越多个sprint,通常是较复杂的sprint。一旦sprint接近尾声并且功能完善,我们将sprint分支“重命名”为“ regression”(这使CruiseControl无需重新配置即可拾取它),然后在cc-build上开始进行回归/集成测试耳。完成所有步骤后,它便投入生产。

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

现在这是对社区的一个问题-由于开发发生在许多分支上,并且CruiseControl的重配置开销很明显,我们在执行持续集成方面遇到了麻烦。有人可以提出建议吗?


我不一定同意结论,但是感谢您对过程的讨论。没有一种万能的解决方案。
RaoulRubin 2014年

0

从我的角度来看,您希望有一组有限的分支可以集中精力。由于您需要测试,代码质量指标以及许多与构建一起运行的有趣事物,因此太多的报告可能会使您错过信息。

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

ps您从哪里获得这些方法参考?-认为这些图形不能代表所有选项

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


它也有更多。但是我觉得功能分支和发布分支是最常见的两种。
KingNestor

0

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

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

他还说,

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

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

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

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

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


戴夫·法利(Dave Farley)和杰兹(Jez Humble)在分支方面的立场简直是错误的。这样做的原因是,它对重要的假设进行了编码:“您将永远不必在功能级别上操作代码,如果这样,则可以进行昂贵的操作”,并且他们的评估基于另一个假设“通过自动化进行合并过于昂贵”合并几乎是不可能的”。如果这两个假设都不成立,那么如果您生活在合并便宜的世界中,但是需要在功能级别上为后端口和安全修复程序操作代码,那么它们的陈述就会崩溃。这是罕见的情况。
吉里·克鲁达

在这些功能在实施中遇到障碍并阻止发布之后,一些公司还需要将这些功能移至将来的发行版中。有时,就像在SaaS产品中一样,可以选择保留代码,但是如果代码已发布给客户,则它可能不是一个选择,因为竞争对手可以对其进行分析。如今,如此多的代码没有被编译,即使已经编译,代码中的定义/功能标志的复杂度也与分支相同。
吉里·克鲁达

-3

我认为您使用的工具在这里很重要。

  • 如果您使用的是Subversion,则坚持使用选项1并从分支中释放。
  • 如果您使用的是GIT,则选项2将非常适合您。

2
使用任何SCM都可以轻松实现功能分支
hdost 2015年
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.