您是在分支中还是在主干中继续开发?

假设您正在开发一个定期发布的软件产品。有关分支和合并的最佳实践是什么?将定期发布的分支分割给公众(或者您的客户是谁) ,然后在主干上继续开发,或者考虑主干的稳定版本,定期将其标记为一个发布,并在分支上进行实验工作。人们认为树干是“黄金”还是“沙盒”?

48285 次浏览

主干通常是主要的开发线。

版本是分支的,通常在分支上完成实验性的或主要的工作,然后当它准备好与主开发线集成时,再合并回主干。

我倾向于采用“发布分支”的方法。后备箱不稳定。一旦到了发布时间,我就会创建一个发布分支,我会更加谨慎地对待它。当最终完成时,我将标记/标记存储库的状态,以便知道“官方”发布的版本。

我知道还有其他方法可以做到这一点——这只是我过去做的方法。

我认为您的第二种方法(例如,标记发布版本并在分支中进行实验,考虑到主干的稳定性)是最好的方法。

很明显,分支在系统被分支的时候继承了系统的所有 bug: 如果修复程序被应用到主干上,如果你把分支作为一种发布周期的终结者来维护,那么你就必须一个一个地去修复所有的分支。如果您已经发布了20个版本,并且发现了一个可以追溯到第一个版本的 bug,那么您将不得不重新应用20次修复程序。

分支应该是真正的沙盒,尽管主干也必须扮演这个角色: 标记将指示代码在那个时间点是否是“黄金”,适合于发布。

主干通常应该是您的主要开发源代码。否则,您将花费大量时间在新特性中进行合并。我曾经见过另一种方式,它通常会导致很多最后一分钟的集成头痛。

我们给我们的产品贴上标签,这样我们就可以在不分发积极开发的情况下快速应对生产紧急情况。

我们在主干上进行开发,除非变化太大、不稳定,或者我们的某个产品即将发布主要版本,在这种情况下,我们创建一个临时分支。我们还为每个产品版本创建了一个永久分支。我发现微软关于 分科指引的文档很有帮助。EricSink 的 关于分支的教程也很有意思,他指出,对于我们其他人来说,适用于微软的东西可能太重了。在我们的案例中,我们实际上使用了埃里克说他的团队使用的方法。

试图根据新的开发管理当前生产代码的维护充其量是有问题的。为了减轻这些问题,一旦测试工作完成并且代码准备好交付,代码应该分支到维护线中。此外,主线应该分支以协助版本稳定化,包含实验性开发工作,或者容纳其生命周期延伸到多个版本的任何开发工作。

只有当代码之间存在可能(或确定)的冲突时,才应该创建非维护分支,而这种冲突很难以其他方式进行管理。如果分支机构不能解决后勤问题,它将制造一个后勤问题。

正常的版本开发发生在主线中。开发人员检入和检出主线以进行正常的发布工作。针对当前生产代码的补丁的开发工作应该放在该版本的分支中,然后在补丁通过测试并部署之后与主线合并。非维修部门的工作应逐案协调。

对我来说,这取决于我使用的软件。

在 CVS 下,我只在“主干”中工作,从不标记/分支,因为否则做起来真的很痛苦。

在 SVN 中,我会在主干中完成我的“前沿”工作,但是当需要执行服务器推送时,会被适当地标记。

我最近换成了 Git。现在我发现我从来不在后备箱里工作。相反,我使用一个命名为“ new-Feature rename”的沙箱分支,然后将其合并到一个固定的“ current-production”分支中。现在我认为,我真的应该在合并回“当前生产”之前制作“ release-VERSIONNumber”分支,这样我就可以回到旧的稳定版本..。

这取决于你的情况。我们使用 Perforce,并且通常有几行开发。主干被认为是“黄金”,所有的开发都发生在分支上,当这些分支足够稳定可以集成时,它们就会被合并回主线。这样就可以拒绝那些不合格的特性,并且可以随着时间的推移提供独立项目/特性可以接受的稳固的增量功能。

合并和追赶主干中的新特性是有集成成本的,但是无论如何你都要忍受这种痛苦。让每个人一起在树干上发展可能会导致一个狂野的西部情况,而分支允许您扩展和选择您想要服用苦涩的整合药丸的点。我们目前在十几个项目中有超过一百个开发人员,每个项目都有使用相同核心组件的多个版本,而且运行得非常好。

这种方法的优点在于可以递归地执行此操作: 一个大的特性分支可以是它自己的主干,如果是这样,其他分支就会离开。而且,最终版本会有一个新的分支,为您提供一个进行稳定维护的场所。

如果你要经历一个发布周期,一个大特性,你会被困在一个分支。否则,我们将在主干中工作,并在构建时分支处理每个产品发布。

以前的生产构建在那个时候被移动到 old _ production _,当前的产品发布总是只是生产。我们的构建服务器所知道的关于生产的全部内容就是如何部署生产分支,我们用一个强制触发器开始构建。

这取决于您的开发工作的规模。并行工作的多个团队不能在同一代码(主干)上有效地工作。如果您只有一小部分人在工作,而您主要关心的是裁减一个分支,这样您就可以继续工作,同时返回该分支对当前的生产代码进行 bug 修复。这是分支的一个简单使用,并且不会太麻烦。

如果您有大量的并行开发,您将希望为每个工作都有分支,但是这也需要更多的纪律: 确保您的分支已经测试并准备好合并回来。安排合并,这样两个组就不会试图在同一时间合并等等。

有些分支的开发时间很长,因此必须允许从主干到分支的合并,以减少最终合并回主干时出现的意外情况。

如果您有一大群开发人员,那么您将不得不进行试验,并对在您的情况下有效的方法有一个感觉。这里有一个来自微软的页面,可能有点用: http://msdn.microsoft.com/en-us/library/aa730834(VS.80).aspx

我已经在一个大型商业应用程序中尝试了这两种方法。

哪种方法更好的答案在很大程度上取决于你的确切情况,但是我会写我的整体经验所显示的迄今为止。

总的来说,更好的方法是: 主干应该总是稳定的。

以下是这种方法的一些指导原则和好处:

  • 在它自己的分支中编写每个任务(或相关的一组任务)的代码,然后您就可以灵活地决定何时合并这些任务并执行发布。
  • 在合并到主干之前,应该对每个分支进行 QA。
  • 通过对每个分支进行 QA,您将更容易确切地知道是什么导致了错误。
  • 这个解决方案适用于任意数量的开发人员。
  • 这种方法可以工作,因为分支在 SVN 中几乎是即时操作。
  • 标记您执行的每个版本。
  • 您可以开发暂时不打算发布的特性,并确切地决定何时合并它们。
  • 对于您所做的所有工作,您都可以从提交代码中获益。如果仅在主干外工作,则可能会使代码大量未提交,因此不受保护,并且没有自动的历史记录。

如果你试图做相反的事情,在主干中进行所有的开发,你会遇到以下问题:

  • 日常构建的持续构建问题
  • 当一个开发人员为项目中的所有其他人提交一个问题时,生产力损失
  • 更长的发布周期,因为您需要最终获得一个稳定的版本
  • 不太稳定的释放

如果您试图保持分支稳定,并将主干作为开发沙箱,那么您就不会具有所需的灵活性。原因是您不能从主干中挑选您想要放入稳定版本中的内容。应该已经混在后备箱里了。

我认为在主干中进行所有开发的一个特殊情况是,当您开始一个新项目时。也可能会有其他情况取决于你的情况。


顺便说一下,分布式版本控制系统提供了更大的灵活性,我强烈建议切换到 hg 或 git。

我使用过这两种技术,我认为在主干上进行开发并将稳定点作为版本进行分支是最好的方法。

上面那些反对的人说:

  • 日常构建的持续构建问题
  • 当一个开发人员为所有人提交一个问题时,生产力损失 项目中的其他人

可能没有使用连续集成技术。

的确,如果您不在一天中执行多个测试构建,比如每隔一小时左右执行一次,那么这些问题将很快扼杀开发的速度。

在白天进行几个测试构建,可以快速地将更新折叠到主代码库中,这样其他人就可以使用它,并且在白天提醒您有人破坏了构建,这样他们就可以在回家之前修复它。

正如前面指出的那样,只有当用于运行回归测试的夜间构建失败时才会发现构建中断,这是十分愚蠢的,而且会很快使事情变慢。

读读 Martin Fowler 关于 持续集成的论文。我们为一个主要项目(3000kSLOC)在大约2000行 Posix sh 中使用了自己的这种系统。

我们遵循主干 = 当前开发流,分支 = 发布(s)方法。在发布给客户时,我们将主干分支,并且只是保持主干向前滚动。您需要决定准备支持多少个版本。您支持的越多,在 bug 修复方面所做的合并就越多。我们试图保持我们的客户不超过2个版本的主干后面。(例如:。Dev = 1.3,受支持的版本1.2和1.1)。

Divmod 的 最终质量发展体系对于保持主干稳定并在分支中完成所有工作的开发过程是一个很好的参考。一个简短的总结:

  • 所有完成的工作都必须有一个与之关联的票据
  • 为完成票据工作的每个票据创建一个新的分支
  • 来自该分支的更改不会在未经另一个项目成员审查的情况下合并回主干

他们使用 SVN 来实现这一点,但是这可以很容易地在任何分布式版本控制系统中实现。

我们正在使用主干的主要发展和分支的发布维护工作。效果不错。但是,分支只能用于修复 bug,不能进行重大更改,特别是在数据库方面,我们有一个规则,即只有模式更改才能在主干上发生,而不能在分支上发生。

都有。

主干用于大部分的开发。但是预计将尽最大努力确保对主干的任何签入都不会破坏它。(部分由自动构建和测试系统验证)

版本维护在它们自己的目录中,只对它们进行 bug 修复(然后合并到主干中)。

任何将使主干处于不稳定或非工作状态的新特性都在它自己的独立分支中完成,然后在完成时合并到主干中。

恕我直言,颠覆约定的问题没有一个放之四海而皆准的答案。

这实际上取决于项目的动态和使用它的公司。在一个快节奏的环境中,每隔几天就会发布一个版本,如果您试图严格地标记和分支,那么您最终将得到一个无法管理的存储库。在这样的环境中,需要时分支的方法将创建一个可维护性更强的环境。

另外,根据我的经验,从纯管理的角度来看,当您选择在 svn 方法之间切换时,这是非常容易的。

据我所知,工作效率最高的两种方法是“需要时分支”和“每个任务分支”。当然,这两者是完全相反的。就像我说的,这都是关于项目动态的。

这实际上取决于您的组织/团队管理版本的能力以及您使用的 SCM。

  • 如果下一个版本(在下一个版本中)可以很容易地计划,那么您最好在主干中进行开发。管理分支机构需要更多的时间和资源。但是,如果下一步不能很容易地计划(在较大的组织中经常发生) ,那么您可能最终会选择提交(成百上千)而不是分支(几个或几十个)。
  • 使用 Git 或 Mercurial,管理分支要比 cvs 和 subversion 容易得多。我倾向于采用稳定的主干/主题分支方法。Git.Git 团队就是用这个。读取: http://www.kernel.org/pub/software/scm/git/docs/gitworkflows.html
  • 在 Subversion 中,我首先应用了中继开发方法。在发布日期方面有很多工作要做,因为每次我都必须挑选提交(我的公司不擅长规划)。现在我算是 Subversion 方面的专家,并且非常熟悉 Subversion 中的分支管理,所以我正在转向稳定的主干/主题分支方法。效果比以前好多了。现在我正在尝试 git.git 团队的工作方式,尽管我们可能会坚持使用 Subversion。

我喜欢并使用 Henrik Kniberg 在 < strong > 多敏捷团队的版本控制 中描述的方法。Henrik 在解释 如何在有多个团队的敏捷环境中处理版本控制方面做得很好(在传统的环境下也适用于单一团队) ,而且没有必要解释他的意思,所以我只是在下面贴出“备忘单”(这是自我解释) :

alt text alt text

我喜欢它是因为:

  • 它很简单: 你可以从图片中得到它。
  • 它工作(和扩展)很好,没有太多的合并和冲突麻烦。
  • 您可以在任何时候(本着敏捷的精神)发布“工作软件”。

为了以防它不够明确: 开发是在“工作分支(es)”中完成的,主干用于 DONE (可发布)代码。检查 < strong > 多敏捷团队的版本控制 的所有细节。

下面是我更喜欢的 SVN 设计:

    • 发展
      • 树枝
        • 特写1
        • 特写2
        • ...
      • 后备箱
      • 标签
      • 后备箱
    • 释放
      • 标签
      • 后备箱

除了需要自己分支的主要特性之外,所有工作都是从开发/主干完成的。在针对开发/主干对工作进行测试之后,我们将测试问题合并到 beta/主干中。如果需要,代码将在 beta 服务器上进行测试。当我们准备推出一些更改时,我们只需将适当的修订合并到发布/主干中并进行部署。

标签可以在 beta 版本或者发布版本中制作,这样我们就可以跟踪 beta 版本和发布版本的特定发布。

这种设计允许很大的灵活性。它还使我们很容易把修订版放在 beta/躯干中,而把其他版本合并到发布/躯干中,如果有些修订版没有通过 beta 测试的话。