23
4

4 回答 4

12

特性分支无疑使重构变得更加困难。它们还使持续集成和部署等事情变得更加困难,因为您正在增加需要构建和测试的并行开发流的数量。您还消除了“持续集成”的中心原则——每个人都在使用相同的代码库并“持续地”将他们的更改与团队的其他更改集成。通常,在使用特性分支时,特性分支不会持续构建或测试,因此“特性分支”代码第一次通过生产构建/测试/部署过程运行是在它“完成”并合并时进入后备箱。这可能会在开发过程的后期和关键阶段引入大量问题。

我持有有争议的观点,即您应该(几乎)不惜一切代价避免功能分支。合并的成本非常高,而且(也许更重要的是)未能“持续集成”到共享代码库的机会成本甚至更高。

在您的场景中,您确定每个客户的功能都需要一个单独的功能分支吗?您是否可以改为在后备箱中开发这些功能,但在它们准备好之前将它们禁用?一般来说,我认为以这种方式开发“功能”会更好——即使它们还没有准备好生产,也可以将它们签入到主干中,但在它们准备好之前将它们排除在应用程序之外。这种做法还鼓励您在精心设计的界面后面保持组件的良好分解和屏蔽。“功能分支”方法为您提供了对代码库进行全面更改以实现新功能的借口。

于 2010-10-29T18:36:55.413 回答
10

我喜欢这个发人深省的论点(“放弃重构”),因为它丰富了讨论:)

我同意在有大量并行代码行时必须非常小心地进行更大的重构,因为冲突会大大增加集成工作,甚至会导致在合并过程中引入回归错误。

正因为如此,重构与功能分支的问题,有很多权衡。因此,我根据具体情况决定:

  • 在功能分支上,我只在他们准备好我的功能以便更容易实现时才进行重构。我总是试图只专注于功能。分支应至少与主干/主线不同。
  • 反过来,我有时甚至有重构分支,在那里我进行更大的重构(恢复多个步骤非常容易,而且我不会分散我的主干同事的注意力)。当然,我会告诉我的团队,我正在做这个重构,并尝试计划在一个清理开发周期中进行(如果你愿意,可以称之为 sprint)。
  • 如果您提到的政治是一件大事,那么我会在内部封装重构工作并将其添加到估计中。在我看来,中期客户在拥有更好的代码质量时会看到更快的进步。很可能他们不会理解重构(这是有道理的,因为这超出了他们的范围......),所以我对他们隐藏了这个
  • 我永远不会做的是重构发布分支,其目标是稳定性。那里只允许进行错误修复。

作为总结,我会根据代码线计划我的重构:

  • 功能分支:只有较小的(如果他们“帮助”我的功能)
  • 重构分支:对于更大的分支,重构目标并不完全清楚(我经常称它们为“涂鸦重构”)
  • 主干/主线:好的,但我必须与功能分支上的开发人员沟通,以免造成集成噩梦。
  • 发布分支:永远不会
于 2010-10-29T18:21:01.113 回答
5

重构和合并是Plastic SCM关注的两个组合主题。事实上,有两个重要的领域需要关注:一个是处理(在合并期间)已在分支上移动或重命名的文件。这里的好消息是,所有“新时代”的 SCM 都会让你正确地做到这一点(Plastic、Git、Hg),而旧的 SCM 只会失败(SVN、Perforce 甚至更老的)。

另一部分是在同一个文件中处理重构的代码:你知道,你移动你的代码,其他开发人员并行修改它。这是一个更难的问题,但我们也通过新的合并/差异工具集关注它。在此处找到xdiff 信息,在此处找到xmerge(交叉合并)。关于如何在此处找到移动代码的一个很好的讨论(与“超越比较”相比)。

虽然“目录合并”或结构合并问题是核心问题(无论系统是否这样做),但第二个问题更多的是工具问题(您的三向合并和差异工具有多好)。您可以免费使用 Git 和 Hg 来解决第一个问题(甚至 Plastic SCM 现在也是免费的)。

于 2010-10-30T16:09:12.450 回答
1

部分问题是大多数合并工具都太愚蠢了,无法理解任何重构。一个简单的方法重命名应该合并为方法的重命名,而不是对 101 行代码的编辑。因此,例如对另一个分支中的方法的额外调用应该自动处理。

现在有一些基于语言解析的更好的合并工具(例如SemanticMerge),旨在处理已移动和修改的代码。JetBrains(ReShaper 的创建者)刚刚发布了一篇关于此的博客。

多年来对此进行了大量研究,最后一些产品即将上市。

于 2014-07-16T09:05:34.487 回答