代码之家  ›  专栏  ›  技术社区  ›  Xavier Nodet

如何处理重构和合并需求之间的紧张关系?

  •  21
  • Xavier Nodet  · 技术社区  · 17 年前

    在交付新版本时,我们的政策是在我们的VCS中创建一个分支,并将其处理给我们的QA团队。当后者发出绿光时,我们会贴上标签并发布我们的产品。分支会一直接收(仅)错误修复,以便我们可以创建技术版本。这些错误修复随后会合并到主干上。

    在这段时间内,主干可以看到主要的开发工作,并可能受到重构更改的影响。

    问题是,在需要有一个稳定的主干(以便合并bug修复成功——如果代码被提取到另一个方法,或者转移到另一个类中,通常是不可能的)和在引入新特性时需要重构它之间存在着紧张关系。

    我们的策略是,在经过足够的时间并且分支足够稳定之前,不要进行任何重构。在这种情况下,可以开始对主干进行重构更改,并在主干和分支上手动提交错误修复。

    但这意味着开发人员必须等待相当长的时间才能在主干上提交任何重构更改,因为这可能会中断从分支到主干的后续合并。不得不手动将bug从分支移植到主干是很痛苦的。在我看来,这阻碍了发展……

    你如何处理这种紧张局势?

    谢谢。

    6 回复  |  直到 15 年前
        1
  •  14
  •   Simon    17 年前

    这是一个实际问题。如果您需要支持多个版本,并且为每个版本都进行了分支,那么情况会更糟。更糟糕的是,如果你也有一个真正的研发部门。

    我的偏好是允许主干以正常的速度继续运行,而不是坚持下去,因为在一个发布时间在商业上很重要的环境中,我永远不会争辩我们应该让代码稳定下来(“什么,你的意思是你在不稳定的状态下发布了它?”).

    关键是确保在将bug迁移到主分支时,为bug修复创建的单元测试被转换。如果您的新代码更改是真正的重新分解,那么旧的测试应该同样有效。如果您所做的更改不再有效,那么在任何情况下都不能只移植您所修复的代码,您需要有人认真考虑新代码流中的修复。

    在管理这类问题很多年之后,我得出结论,您可能至少需要4个代码流来提供适当的支持和覆盖,以及一组相当严格的过程来管理它们之间的代码。这有点像能画出任何四色地图的问题。

    在这个问题上,我从来没有找到真正好的文献。它将不可避免地与您的发布策略和您与客户签订的SLA相关联。

    附录:我还应该提到,有必要将分支合并作为特定的里程碑写入到主分支的发布计划中。如果您有一组辛勤工作的开发人员在执行它们的工作实现特性,那么不要低估将分支集合在一起可能需要的工作量。

        2
  •  5
  •   Community Mohan Dere    9 年前

    在我工作的地方,我们为每一个重要的更改(特性添加或错误修复)创建临时的、短暂的(不到一天——几个星期)工作分支。主干是稳定的,并且(理想情况下)可以随时释放;仅 完成 项目合并到其中。从主干提交的所有内容每天都会被合并到工作分支中;这在很大程度上是自动化的(我们使用Hudson、Ant和Subversion)。(这是最后一点,因为通常情况下,解决任何冲突的时间都要早于解决冲突的时间。)

    我们目前使用的模型在很大程度上受到一篇优秀文章的影响。( which I've plugged before )作者:Henrik Kniberg: Version Control for Multiple Agile Teams .

    (在我们的例子中,我们有两个Scrum团队在一个代码库上工作,但是我开始认为这个模型即使与一个团队一起工作也会有好处。)

    额外的分支和合并会带来一些开销,但实际上,一旦习惯了它并使用工具(例如 svn merge --reintegrate 很方便。不,我并不总是创建一个临时分支,例如,对于较小的、低风险的重构(与当前正在工作的主要项目无关),只需一个提交到主干就可以轻松完成。

    我们还维护了一个旧的发布分支,其中关键的错误会不时地被修复。不可否认,如果与分支相比,主干中的某些特定代码部分发生了显著的变化,那么可能存在手动(有时是冗长的)合并工作。(随着我们不断地从主干(内部)中释放增量,并让市场营销和产品管理部门决定他们何时需要进行外部发布,这一问题有望减少。)

    我不确定这是否直接回答了您的问题,或者您是否可以将其应用于您的环境(与单独的QA团队和所有人一起),但至少我可以说,您描述的紧张不存在于我们,我们可以随时重构。祝你好运!

        3
  •  1
  •   Dan    17 年前

    我认为可以通过在开发过程中添加以下成分来处理这种紧张关系:

    1. 持续集成
    2. 自动功能测试(我假设您已经用单元测试计数了)
    3. 自动化交付

    通过持续集成,每次提交都意味着一个构建,在这个构建中,所有单元测试都会被执行,如果出现任何问题,您都会受到警告。您开始更多地使用head,并且不太容易分支代码库。

    通过自动化的功能测试,您可以通过单击按钮来测试应用程序。一般来说,由于这些测试需要更多的时间,所以它们是每晚运行的。 有了这个,版本控制的经典角色开始失去重要性。您不需要根据版本及其成熟度来决定何时发布,它更像是业务决策。如果您已经实现了单元和功能测试,并且您的团队正在提交测试代码,那么head应该始终处于可以发布的状态。错误会不断被发现、修复并发布,但这不再是一个循环过程,而是一个连续的过程。

    你可能会有两种类型的诽谤者,因为这意味着改变一些根深蒂固的做法。首先,对于管理者来说,持续交付的范式转变似乎是违反直觉的。__Are____157;如果你看一下Linux或Windows发行版,这正是他们正在做的:将发行版推向客户。而且,由于您使用了一套自动化测试,危险会进一步减少。

    接下来是质量保证团队或部门。(有些人认为问题在于他们自身的存在!)他们通常不喜欢自动测试。它意味着学习新的,有时是复杂的工具。在这里,最好的方法是通过这样做来布道。我们的开发团队开始致力于持续集成,同时用 Selenium . 当质量保证团队看到这个工具在运行时,很难反对它的实现。

    最后,Thurth是我描述的过程并不像在开发过程中添加3个入口那么简单。它意味着对软件开发方式的深刻改变。

        4
  •  1
  •   Xavier Nodet    16 年前

    也许Git(或其他dvc)在处理更新代码的合并时更擅长,因为它们(实际上)管理更改,而不仅仅是比较文件…AS Joel says :

    使用分布式版本控制,合并很容易并且工作良好。因此,您实际上可以拥有一个稳定的分支和一个开发分支,或者为您的QA团队创建长寿命的分支,在那里他们在部署之前测试事物,或者您可以创建短命的分支来尝试新的想法并了解它们是如何工作的。

    不过,还没试过……

        5
  •  0
  •   Scott Langham    17 年前

    在我工作的地方,我们继续在主分支中进行重构。如果合并变得棘手,他们只需要在一个特别的基础上处理,他们都能做到,但偶尔需要一些时间。

        6
  •  0
  •   Xavier Nodet    17 年前

    也许我们的问题来自这样一个事实:我们的分支必须有相当长的使用寿命(长达18个月),并且必须对它们进行许多修复。

    确保我们只从非常稳定的代码进行分支可能会有所帮助,但不会那么容易…:。(