多个功能分支与持续集成

20

最近我阅读了一些关于持续集成的内容,发现有一个场景我不知道如何妥善处理。

我们有一个稳定的主干/主线(mainline/trunk)分支,并为特性创建分支。每个开发者会定期从主干合并到他们自己的特性分支以保持其更新。但是,完全有可能会创建并在数周或数月内对两个或更多特性分支进行工作。在此期间,软件的许多版本可能已经发布。这就是我的困惑所在。

很可能一个特性分支的更改会与其他特性分支发生冲突。持续集成建议您每天将代码合并到主干中,这样可以快速解决冲突。然而,您可能不希望将特性代码合并到主干中,因为它可能尚未完成或您可能不希望该特性在下一个版本中可用。那么,在遵循持续集成原则的前提下,如何处理这种情况呢?

6个回答

11

在正确的CI中,没有特性分支。请使用特性开关代替。


10
我不赞同使用这种功能切换的做法。一个源代码控制软件有很多功能,其中之一就是负责管理修改和备份源代码。开发者应该能够依靠源代码控制的可靠性,即使他们的代码无法编译、构建或不稳定,也不应该受到影响。并非所有的修改都可以在短时间内完成。分支可以让你的代码在不冒风险破坏主干的情况下保持安全。 - Nicolas Bousquet
2
你所做的每一个更改都可以很小,这样你就永远不会提交无法编译的代码。这是 CI 的真正含义 :) - Aleš Roubíček
20
这是过于简化了:虽然我写了一个功能标志实现,并且喜欢这个想法,但它们不是万能药。并不是每个项目或每个功能都适合在运行时切换,并且不能通过标志禁用每个人可能引入的错误或将被标志基础测试捕获。人们可以合理地希望具有至少持续几周并定期进行测试的功能分支。 - poolie
6
#ifdef SOME_FEATURE_IS_ENABLED(或者它的Web2.x解释语言亲戚)是一个可怕的、可怕的想法。 - slacy
10
特性开关是一个糟糕的想法。这种方式几乎不可能切换并隔离版本之间的更改,因为正在开发的所有特性并非完全相互隔离:它们可能共享大量代码,或者被切换关闭的特性的工作可能包括对公共库的更改,所以关闭开关不能隔离这种变化。不完整的特性代码不应该出现在开发/主干分支中。如果来自主干的向前合并和向后合并不太远,请使用特性分支与CI一起运行,没有理由不能这样做。 - MrLane
显示剩余3条评论

9
完整表述的想法在这篇文章中有更详细的解释:每天从主干/发布分支合并到功能分支,但只有在某个功能符合“完成”的定义后才会向另一个方向合并。
由一个功能团队编写的代码一旦完成就会被推入主干,然后“分发”给其他团队,在日常合并过程中可以处理冲突。
除非所做的更改足够小,可以在可接受的时间范围内提交到功能分支,否则这并不能满足Nick想要将版本控制系统用作备份工具的愿望。
我个人不会在完成之前重新集成代码到发布分支,虽然我从未真正尝试过,但我相信为未完成的工作构建特性切换也有其自身的问题。

你要么在进行持续集成,要么不在进行。在持续集成下,每天都应该将提交的代码整合到主线上。这意味着你不仅要从主干合并到功能分支,还要每天将功能分支合并回主干,这违背了设立功能分支的初衷。简而言之,功能分支与持续集成不兼容。 - Jake

3
我认为他们的意思是将主干合并到特性分支中,而不是相反。这样做,特性分支不会偏离主干太多,容易进行合并。 Git开发人员在提交功能之前,在主分支上将功能分支重新基于重放。

这就是我说的,但我可能没有表达得很好。我的问题特别涉及到拥有多个功能分支并希望遵循CI实践所涉及的问题。 - Phil Hale
1
多个功能分支并不特殊;每个分支都必须容易地合并到主线并能够独立工作。如果将另一个分支合并,则该更改需要传播到其他功能分支,这可能需要手动解决 - 这是无法避免的,但至少您是在功能分支中而不是在主线中进行操作。 - Simon Richter

2
根据我的CI经验,建议您像其他人建议的那样保持功能分支与主线更改同步。这在几个版本中一直有效。如果您使用的是Subversion,请确保启用合并历史记录。这样,当您尝试将更改合并回线路时,它只会看起来像您正在将功能更改合并到线路上,而不是尝试解决您的功能可能与主线存在的冲突。如果您使用更高级的VCS(如git),第一次合并将是变基,第二次将是合并。
有一些工具可以帮助您更顺利地完成这些任务,例如Bamboo功能分支

1
特性分支回归到主线,经常是持续集成的重要特性。有关详细信息,请参见本文

1

现在有一些很好的资源展示了如何结合CI和特性分支。 BambooFeature Branch Notifier 是一些可以参考的方式。

这篇文章是另一篇相当长的文章,展示了所谓的分布式CI的优点。以下是其中的一段摘录,解释了它的好处:

分布式 CI 对于持续部署有优势,因为它保持了一个干净和稳定的主干分支,可以随时部署到生产环境。在集中式 CI 过程中,如果代码不能正确集成(构建失败)或者存在未完成的工作,将会存在不稳定的主干分支。这对于迭代发布计划非常有效,但是对于持续部署来说会创建瓶颈。在 CD 中,必须保持从开发分支到生产环境的直接路径干净,分布式 CI 通过仅允许将准备好的代码放入主干分支来实现这一点。

唯一可能具有挑战性的是保持分支构建的隔离性,以避免将其分支构建推送到二进制存储库中。 Bamboo 似乎解决了这个问题,但不确定在 Jenkins 中是否如此简单。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接