奇怪的公司发布周期:进行分布式源代码控制吗?


13

抱歉,这篇文章很长,但我认为值得。

我刚从一家小型.NET商店开始,其运作方式与我工作过的其他地方有很大不同。与我以前任职的职位不同,此处编写的软件针对多个客户,并且并非每个客户都同时获得最新版本的软件。因此,没有“当前生产版本”。当客户确实获得更新时,他们还将获得自上次更新以来可能已添加到软件中的所有功能,而这可能是很久以前的事了。该软件是高度可配置的,并且可以打开和关闭功能:所谓的“功能切换”。此处的发布周期非常紧张,实际上它们没有按计划进行:功能完成后,软件便部署到了相关客户。

该团队仅在去年从Visual Source Safe迁移到Team Foundation Server。问题是他们仍然像使用VSS一样继续使用TFS,并在单个代码分支上强制执行Checkout锁定。每当将错误修复发布到现场时(甚至对于单个客户),他们都只需构建TFS中的内容,测试该错误是否已修复并部署给客户!(我自己来自制药和医疗设备软件背景,这真是难以置信!)。结果是半熟的开发人员代码甚至未经测试就投入生产。Bug总是会渗入发行版中,但是如果刚获得构建的客户通常不使用该bug所在的功能,他们将不会看到这些bug。主管知道这是一个问题,因为该公司正在逐渐发展壮大突然之间有一些大客户加入,而一些小客户也加入了。

有人要求我查看源代码控制选项,以消除错误的代码或未完成的代码的部署,但又不牺牲团队发行版的某种异步特性。在我的职业生涯中,我曾使用过VSS,TFS,SVN和Bazaar,但是TFS是我大部分经验的去处。

以前与我合作的大多数团队都使用Dev-Test-Prod的两个或三个分支解决方案,其中一个月的开发人员直接在Dev中工作,然后将更改合并到Test然后是Prod,或者在“完成时”升级,而不是在一个固定的周期。使用定速巡航或团队构建的自动化构建。在我之前的工作中,Bazaar被使用在SVN之上:开发人员在自己的小型功能分支中工作,然后将其更改推送到SVN(与TeamCity绑定)。很好,因为很容易隔离更改并与其他人的分支机构共享。

在这两种模型中,都有一个中央的dev和prod(有时是测试)分支,通过该分支推送了代码(标签被用来标记生产该版本的prod中的构建...这些都被制成了分支以修复错误。发布并合并回开发人员)。但是,这确实不适合此处的工作方式:没有命令何时发布各种功能,何时完成将它们推入。

有了这个要求,我看到的“持续集成”方法就失效了。为了获得与持续集成的新功能,必须通过dev-test-prod来推送它,这将捕获开发中所有未完成的工作。

我认为,要解决此问题,我们应该使用没有开发测试prod分支的大量功能分支模型,而是将源作为一系列功能分支存在,当开发工作完成时,这些功能分支将被锁定,测试,固定,锁定,经过测试然后发布。其他功能分支可以在需要/想要时从其他分支获取更改,因此最终所有更改都会被其他人吸收。这完全符合我上一份工作所经历的纯粹的Bazaar模型。

听起来如此灵活,但似乎没有某个开发主干或prod分支似乎很奇怪,我担心分支无法进行重新集成,或者后期的微小更改永远不会被其他分支和开发人员所抱怨。合并灾难...

人们对此有何想法?

第二个最后一个问题:我对分布式源代码控制的确切定义有些困惑:有些人似乎暗示它只是没有像TFS或SVN这样的中央存储库,有人说这是关于断开连接的(SVN断开了90%并且TFS具有功能完善的离线模式),其他人则说这与功能分支和分支之间没有父子关系的合并的简便性有关(TFS也具有无基础的合并!)。也许这是第二个问题!


Answers:


5

DVCS的定义是什么?

分布在DVCS意味着版本库的每一个克隆拥有所有的信息需要提交,更新,分支,合并或搜索该库的任何修改,而没有触及服务器。您唯一可以脱机执行的svn操作实际上是编辑文件 -几乎所有svn命令都需要服务器访问权限,包括执行grepping an之类的简单操作svn log,因此实际上它接近0%而不是90%!

任何权威的中央存储库,你可能会在DVCS工作流程设置是只是一个克隆,而唯一一次你需要互动与它是当你往下拉其他人更新或当你把自己的更改,以便其他人可以看到他们,几乎所有其他一切都可以离线完成。

哪种分支模型合适?

我一直处于你现在所处的境地。这样的系统可能是真正的痛苦,但是您必须了解它们变成这样的务实原因,并意识到它们并非无法救赎。已经开发了许多工具,可以帮助管理这种复杂性

首先,无论您做什么,都不要向人们展示成功的git分支模型,它只会使他们感到困惑并将其关闭。相反,开发自己的模型以反映您现有的工作流程,但解决现有工作流程的问题

您可能需要考虑的一些资源包括git 子模块之类的东西,它将允许不同的客户版本指定客户配置,应用程序模块和库的不同组合。另一个选择是使用补丁程序管理系统来应用客户/产品特定的补丁程序队列。

与当前的工作流程相比,这两个选项都将提供更大的灵活性,透明度和安全性,并且比更复杂的仅分支策略更易于使用。我当然希望在您遇到这种情况时能够使用这些工具。

有关这些选项的更多信息,请参阅我对在模块化系统上使用版本控制的策略的回答,如何在Git存储库内部使用Subversion存储库?以及用于多个公司的应用程序的源/版本控制

最终,这确实是您必须与团队其他成员一起开发的东西。如果您想提出一个比现有产品更好的产品,并且能够获得其他开发人员的支持,那么您将拥有一个轻松得多的时间。

最重要的是向同事展示您的建议如何使他们的生活更轻松。一旦他们确信了,您将有更大的机会让管理层放弃对TFS 的投资,并开始使用更适合您的工作方法的模型。


1
+1查找适合您
jcmeloni 2012年

1
+1表示“让生活更轻松”。这是主要的动机。

5

首先,DVCS是解决您遇到的问题的重要工具-使用的版本控制工具并不是必须解决的问题的根源。也许DVCS解决方案的某些方面比TFS“更好”,但目前还不需要解决。

您已经确定需要一个适合您的组织的可行的分支结构-我想您会发现您还有一个主干,当功能完成时,它会合并回主干并关闭。关于如何实现常见依赖也有一些不错的想法。

您还需要持续进行集成工作(没有理由为每个活动分支没有自动化构建,以使您确信可以构建该分支并通过相关测试)。如果提交(或至少是“推送”)没有触发我的构建,我会感到不舒服。

而且,您需要开始进行所有级别的自动化测试,尤其是单元测试和集成测试,以开始减少新错误潜入野外的机会。最后这是巨大的,我仍然在努力奋斗,但是很明显,一旦您知道可以构建所有东西,这将是最大的价值。

您需要将其结合在一起,以确保部署包来自构建服务器,并且部署要尽可能自动化(您应该能够以最小的工作量和最小的压力从构建服务器工件过渡到实时部署的代码)。

嗯,我假设有一个很好的有序的问题跟踪设置……您也需要这样做,并确信它已被正确使用。理想情况下,您希望实时应用程序将错误自动反馈到该系统(或进行分类)。

最后,不要试图立即解决所有问题-在我看来,构建和测试是您应该首先关注的地方。


我中有一部分人同意DVCS也可能是一个红鲱鱼:我当然同意,问题的根本在于流程。我认为持续集成在这里可能会很麻烦,并且不会进行单元测试,因为这将被视为过多的工作。该代码库无论如何都无法测试,因为它是紧密耦合的单片系统,并且所有内容都基于具体类型:无接口。
MrLane 2012年

@MrLane-我知道要向人们解释这一点很困难,但是自从我开始以TDD方式进行开发以来,我越来越相信我没有时间编写测试。
Mark Booth 2012年

1

第二个问题更简单,更简短,因此我将尝试从它开始

DVCS是一种系统,在没有附加层(个人,非规范定义)的情况下,不可能有任何“权威”代码源(“约定”除外,使用时)和数据的P2P交换。

关于题目的第一个问题

恐怕公司必须重构工作流程并重新考虑样式,才能获得“某种程度上可管理且可预测的代码”。我不能说TFS(除了个人意见和感觉,它在Version Control部件中是弱系统/无基础合并是邪恶的/),但是对于您所处的任何VCS(“产品”都是独立的“模块”集,每个“客户”都会获得不同的“产品”-这个假设是正确的吗?)我宁愿将模块的开发分为多个单独的分支,将“产品”作为“超级模块”(也是分支?),每个模块都与模块的特定修订版相关联-分支,模块开发使用每个任务分支范例(模块分支仅由合并集组成)。

这样,您始终可以知道,构成每个“产品”的是哪个“集合”(即一组模块及其相应的修订版),可以进行CI(针对已完成和合并的任务分支),单元测试和构建


1

广告主要问题:我相信您在说的正是git成功分支模型(以及支持它的辅助工具git flow)所针对的。有一个主分支,该分支始终处于可部署状态,并在功能分支上进行所有工作。

您也可以使用git本身使用的过程,该过程是从相同的基本原理派生而来的。在git-core开发中,所有工作都发生在功能分支上。功能分支将提交给集成商,集成商运行脚本以将所有特征合并以创建一个名为pu(建议更新)的分支。有很多人使用此分支并对其进行测试。

您可以让持续集成服务器代替集成器,在构建开始时执行此合并。这样,只要团队中的任何人将更改作为功能分支推送到中央存储库(可能使用某种命名约定来告诉应该选择哪个分支)。

在git中,功能分支会转到nextmaster或者maint取决于它针对的是哪个版本(主要是用于错误修复当前版本,主要是用于当前准备中的版本,下一个是之后的版本),但是您没有那么多。

当这些功能pu(在git维护者的术语中为“烹饪”)中时,将它们倒带,pu并且每次都丢弃并再次创建分支,这使它更易于检查,但不适合进行其他工作。将功能分支合并到主线之一时,将其关闭以进行倒回,并在进行新的提交时进行进一步的修复。

我个人建议git最好。最初学习起来有点困难,因为它有机地增长了,但最终看起来最灵活。但是git,mercurial和bazaar这三种分布式系统中的任何一个都可以为您提供良好的服务(并且您甚至可以经常将它们混合使用,例如,mercurial可以从git存储库中拉入/推入,bazaar也可以)。

第二个问题:有人告诉我,“分布式”通常意味着您可以移动对象并保持其身份。分布式版本控制正是这么做的:克隆存储库,它包含相同的提交,并允许对它们执行相同的操作。分支的易用性和断开连接的操作是主要的用户级功能,遵循移动提交的原理和允许该操作的有向图布局。


1

不幸的是,没有已知的解决方案来解决代码中的错误:)

因此,您只是想防止未完成的签入陷入主发行版,而唯一的答案是每个开发人员的分支工作合并。我在以前使用Clearcase的公司中做到了这一点,但效果很好(即使我们必须有十几名Clearcase管理员)。

现在,我还假设您对每个客户当前拥有的产品版本执行错误修复...,因此您遇到了合并问题,使问题修复从版本A一直到版本Z一直存在。没有简单的处理方法这个,但是您必须为每个出厂版本都拥有一个分支。解决此问题的最佳方法是仅将功能分支保留在最新版本上,并让客户升级以获取新功能,同时,直接在发行分支上执行错误修复并将其向上合并到所有其他发行分支中完成时。

不太好,但是效果很好。您可以使代码井井有条,并且完全分开。对于其他开发人员来说,它也很容易理解-直接在“代码”上的小错误修正,在专门的分支上完成了几行以外的事情,只要他们愿意,就可以花些时间完成它。(您将必须解决合并问题,并向他们保证,如果2个开发人员同时使用2个功能,就可以了!)

不久后,您也可以在发行分支上引入功能分支,在该分支中修复了错误,然后将其合并,但是恕我直言,这通常比所需的工作更多。但是,如果您需要向旧版本中添加功能,则需要遵循这种方法-将一个分支分支到一个版本分支中,然后将代码合并回该版本中,并将更改向上合并到以后的版本中。这将使您的测试团队非常不高兴,因为需要反复测试多个版本,因此发布会严重延迟,而开发团队则很不满意,因为他们必须进行大量合并才能开始使用新代码(在我当前的公司中)发生这种情况,主要是由于我们总是需要尽快完成大量工作。

DVCS:

基本上,DVCS是每个人都有自己的服务器存储库副本的地方。它具有一些优点(尤其是在通信有限的分布式团队中),但是也有一些缺点,因此请在切换到DVCS之前先进行检查。如果您是Windows商店,那么您可能会发现Mercurial是最适合您的DVCS。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.