28

假设您有几个用于现有软件版本的维护分支。一些开发人员正在维护分支中进行直接更改,并定期合并到主干中。现在对主干代码线进行了广泛的重构,计划在即将发布的主要版本中发布。但这使得维护分支从根本上与主干中的代码不兼容,因为它们可能依赖于不再存在的代码,例如。

您在实践中如何处理这种情况?

4

14 回答 14

22

我认为分支维护开发人员有责任将适当的更改合并到主干的当前状态。有几种可能性:

  1. 主干中的代码没有改变,补丁应用没有冲突。
  2. 主干中的代码已更改,补丁已应用,但需要手动合并。
  3. 后备箱中的代码已完全更改,无法应用补丁。开发人员必须评估主干中是否存在相同的缺陷,并在需要时应用等效修复。

案例 1 和 2 是通常的维护开发路径。案例 3 是您正在考虑的情况,中继代码不能接受任何形式的维护补丁。如果开发者自己不能确定主干中是否存在同样的问题,那么他应该将问题输入问题跟踪系统。这个问题将指导主干开发人员考虑维护分支中补丁的原因以及相同的缺陷是否仍然存在。为后备箱中可能存在的缺陷输入新问题应该是维护开发人员的最后手段。

让维护开发人员尝试将补丁应用到更新的主干的好处之一是增加他们对新代码库的熟悉度。最终,他们将用完维护工作,需要使用新的主干。至少具有基本的熟悉程度将大有裨益。

于 2009-02-21T12:55:08.967 回答
3

这最终是一个关于团队沟通的问题,而不是一个简单的分支/合并问题。

与所有此类情况一样,第一步是意识到您有问题。这是你所做的事情。

然后,您需要提醒整个团队注意这个问题。

一旦你这样做了,我认为有两种不同的路径:

  1. 如果不经常使用维护分支,例如发布的代码相当成熟且没有错误,您可以决定冻结代码。每个开发人员必须在 10 月 32 日之前完成他/她的工作,并将这些更改合并回主干。然后应关闭或冻结分支。然后,可以在主干中继续工作,并且可以发布新软件。

  2. 如果分支中有频繁或紧急的更改和修复,这个问题就更复杂了。仍然需要冻结代码,否则主干将被多次破坏。但是在这里,开发人员仍然需要在此期间修复问题并将其提供给客户。我建议在主干代码冻结后分支中的每次更改都应记录在错误跟踪数据库中(在每种情况下都必须),并特别指出这已在分支 N 中修复但尚未合并到主干。这需要仔细记录,以便记住每个相关的细节。

    在主干重构之后,但在它被清理、抛光、标记和发布之前,检查错误数据库,特别是在分支中修复的项目,而不是主干。它们仍然相关吗?如果有必要,现在是时候再次更改代码了。这可能意味着短时间的双重工作,但希望代码现在更易于维护。

    一旦所有已知问题都解决了,就可以发布新版本,并且可以关闭旧分支。

于 2009-02-22T09:33:24.170 回答
2

我能想出的唯一答案是在开始重构之前创建一个维护主干分支。您维护这个新分支,就好像它是一个主干一样,像往常一样合并与发布分支的更改。展望未来,您必须小心混合来自新旧源库的更改。

另一种选择是尝试类似MolhadoRef关于 MolhadoRef 和 Refactoring-aware SCM 的博客文章),如果您能找到满足您需求的可用于生产的等效系统。从理论上讲,这是具有重构意识的源代码控制。我有一段时间没有研究它了,但最后我记得它还远不是一篇研究论文和概念验证。

于 2009-02-21T17:55:21.103 回答
2

在实践中,您可能需要做额外的工作才能使您的新更改向后兼容。

  • 第 1 步:开始重构组件。在每一步中,保留旧接口,但让它将调用迁移到新实现。请注意,随着新接口/API 的建立,这可以通过几个步骤完成。单元测试应该能够验证从旧到新的迁移是否正常工作,但是这一步很可能仍然会产生测试/QA 开销。

  • 第 2 步:新版本已投入生产;确保每个人都知道它。此时,旧版本没有添加任何新功能,所有新的(或更改的)调用者都使用新版本。

  • 第 3 步:找到调用旧接口的所有内容(使用工具来执行此操作),并将所有内容更改为调用新接口。这也可能会产生大量的测试/QA 开销。不过,每个调用者都可以一次提交/释放一个。

  • 第 4 步:此时,新版本已上线,并且没有访问旧版本的调用者。安全地删除它。

请注意,如果 API 是公开的并且您无法控制调用它的人(例如 Microsoft 等公司),您可能永远无法通过第 2 步。

这个过程可能很慢,并且需要大量的纪律、沟通和测试。但在替代方案是永远追赶/整合的情况下,这可能是一个合理的选择。

于 2009-02-22T16:14:29.137 回答
2

鉴于修复错误的大部分成本是重现问题和测试修复。你能否编写一个适用于所有分支的自动化测试,即使每个分支的代码修复方式都不同?

于 2009-02-27T12:46:57.033 回答
1

当您的维护分支不再与主干兼容时,是时候为此目的创建新分支了。也就是说,在大项目开始时,您要确保所有开发人员都知道新功能将出现在主干中,以便他们可以更好地选择在何处实施修复。据推测,如果主干中发生的代码更改如此显着以致无法支持维护,则应将维护合并到主干中。

于 2008-10-28T19:13:15.567 回答
1

创建一个维护分支并让它充当主干和版本分支之间的缓冲区。

对版本分支的更改进入维护分支,然后只有在可以的情况下才会传播到主干,反之亦然。

不过,我不认为有灵丹妙药。随着分支越来越分歧,它们将变得不兼容,因此您必须考虑支持它们多长时间。否则,您最终可能会不止一次地修复错误,但对于不同的分支略有不同。

于 2008-10-28T19:18:02.513 回答
1

这可能是一个工作量很大的建议,但我首先想到的是将所有内容合并回主干。每个人的更改都会合并回主干副本并将它们保存在一起。然后,根据需要在主干上重构。现在你有一个工作的主干,所有的修复都放在一起。

不幸的是,这意味着维护分支中的任何修复都需要放在一起并进入中央主干。我意识到这将是一大堆工作,但我认为这将允许重构所有内容,并且维护分支的任何改进都属于主分支。我可能对此很天真,但我并没有真正参与过生产项目,也不知道维护分支上到底有什么。我认为这将使后备箱完全更新,并且您的所有维护改进都将集成到后备箱中。

我认为这样做可以最大限度地提高所有分支的质量,并使重构扩展到重构后要分支的所有分支。这也是将您的团队聚集在一起进行所有合并的好方法。

于 2009-02-23T22:41:42.520 回答
1

我看到两种不同的方法来解决这个问题:

1.

不应在主干中对主干进行重大更改(如重大重构)。它们应该在一个分支中完成,并在它们足够稳定时合并回主干。

定期对主干的更改应与其他维护分支合并。仅在主干稳定时才将重构合并到主干的原因是因为这些将被合并到维护分支中。但是,如果没有机会使这些更改稳定,那么选项 2 会更好。

在对维护分支进行更改后,可以将它们合并回主干。

2.

创建维护分支的一个分支(每个分支一个)。这将用于将主干与每个维护分支合并。(请注意,为了限制维护分支的数量,应使用 SVN 外部或等效项)。

在主干中进行所有重构并将其合并到维护分支的分支中。当您发布或认为主干稳定时,将维护版本的这些分支合并回各自的分支。然后这些可以依次合并回主干。

实际上,每个维护分支都变成了“子干线”。

请注意,此方案突出了未来维护和前期维护之间的权衡。代码中的分支和差异越多,需要的前期维护就越多。好的部分是增量维护要容易得多。

于 2009-02-27T06:25:00.417 回答
0

我只能回应其他人所说的话,同时强调补丁队列可能成为的真正痛苦。

如果你有一个预定义的(和铁定的)合并窗口,你应该只有两个星期的地狱来处理。

于 2009-02-21T13:11:29.473 回答
0

你必须这么多的分支正在工作吗?

主干上的工作是不是因为项目计划说当前版本已经准备好发货而才开始,所以它已经发货了?

您是否有很多维护分支,因为客户出于某种原因拒绝升级到最新版本?如果是,请说明原因。

你有太多的旧版本是因为下一个主要版本之前的差距太大了吗?

您是否会向不会升级的客户收取更多的维护费用,因为它会花费您更多?

回复评论:

微软仍然支持 Windows XP,即使 Vista 已经出局

确实如此,但是即使 XP SP3 已经出局,Microsoft 仍然不支持 Window XP SP1。

这不是非黑即白,即使你不能停止支持旧版本,你也可以减少你支持的旧版本的数量。问题是销售/支持喜欢说“是”,但开发会很痛苦,所以你需要让你的销售/支持人员站在一边。

于 2009-02-27T12:45:15.930 回答
0

我认为您最好的选择是进行迭代重构。与其在私有分支上一次性完成所有重构,不如一次一个阶段进行。在分支上进行几组更改,然后当您知道它们稳定时,将它们合并到主干。在其他分支上工作的开发人员将负责不断使他们的分支与主干保持同步。

与合并差异很大的大型分支相比,经常合并一小部分更改要少得多。合并的次数越多,最终要做的工作就越少。

于 2009-02-27T14:38:23.007 回答
0

在我们的项目中,我们主要不修复版本维护分支中的更改。如果有错误并且

  1. 它发生在主干和主分支中,我们在主干中修复它,然后将更改合并到维护分支(这可以干净地发生,或者需要更多工作,在这种情况下,我们决定是否不是更好仅在较新版本中修复了该错误)。
  2. 它只是在维护分支中,后备箱中可能有一些修复之王,我们去第一场景。
于 2009-02-27T16:24:21.990 回答
0

正如格雷格指出的那样,有几种可能的情况。

我会添加一个需要手动合并的案例(2.5),但是由于您已将方法从其原始位置移开然后应用了一些更改,因此很难合并,特别是如果“基础”代码也被修改了在“维护”分支中。这并不像听起来那么罕见,实际上将方法移动到不同的位置并应用小修复是很常见的。

我们开发了一个名为 Xmerge(交叉合并)的工具,这是迈向重构感知合并的第一步。它还不是自动的,但它有助于处理涉及移动代码的艰难合并。它在此处进行了描述,并且已经集成在 Plastic SCM 2.7 中。

我们正在努力:自动移动检测,还能够“交叉合并”到多个目标文件(您将代码移动到另一个文件,这也很常见)。

于 2009-04-27T22:17:07.653 回答