【问题标题】:Version control "best practice"版本控制“最佳实践”
【发布时间】:2009-09-07 16:33:19
【问题描述】:

我一直在阅读这里关于版本控制主题的所有问题,但我认为我没有找到一个看起来像我自己的场景。

场景是:

我们有一个中型/大型 Web 应用程序,它有(至少应该有)一个部署到所有客户端的核心。当我们向客户演示应用程序时,几乎所有客户都要求更改布局,或列表中的数据,或数据输入表单中的字段等......几乎所有这些更改都需要更改剩余的“应用程序的层”。

在我们目前的情况下,我们使用 CVS(与 tortoiseCVS)并且我们不使用分支,我们使用标签来区分应用程序的代码更改(是的,我知道这很糟糕)。当我们想要向特定客户发布版本时,这会带来很多问题,以及签入更改等......准备发布总是需要大约 1-2 天的工作,有时它仍然会中断。

有时,来自客户端的请求也会包含在核心中以分发给所有客户端。

所以我的问题是:分支是隔离对应用程序的自定义客户端版本的更改的最佳方式吗?每当新客户要求定制时,我们应该分支吗?还是我们应该将其视为一个完全不同的项目,具有不同的存储库?

必须维护所有不同的版本,而且我听说分支是“临时的”,我怀疑分支是否是最佳解决方案。

感谢您的回复。

安东尼奥·迪亚斯

【问题讨论】:

  • 只想对所有回复表示感谢。即使这不是最好的策略,我也会尝试“客户分支”策略。每个客户端都有它自己的长期存在的分支,每个客户端都有它的“主”和“开发”分支。至少我认为它会比我们现在拥有的更好。谢谢大家。

标签: cvs branch


【解决方案1】:

我不知道您为什么认为分支是临时的——只要您希望它们存在,它们就会存在。

您的应用程序听起来好像可以从重组中受益,以实现更多模块化功能,但与此同时,您可以将主要功能开发为主干,每个客户版本都成为它自己的分支。

然后可以根据需要将对核心代码的修改合并到每个分支中。客户特定的更改可以在该分支上单独进行,也可以在以后合并回主干。

为每个客户使用单独的存储库听起来完全是错误的做法,因为这会导致存储库之间的公共代码重复。

【讨论】:

  • 我同意这一点,并补充说您可能应该考虑采用更现代的版本控制系统,它可以更好地处理分支和合并——它会让您的生活更轻松从长远来看。
【解决方案2】:

首先,您最好还是咬紧牙关重构代码以减少所有这些自定义的影响。有一些很好的模式允许这种类型的场景(配置驱动、插件、软件工厂)。

话虽如此,如果应用程序如您所描述的那样(每个客户端都需要对核心进行广泛的更改),您可能想探索使用编译器指令来隔离单个客户端更改是否比分支更适合您。分支的问题(我相信您已经发现)是放置在一个分支中的修复通常需要传播到所有其他分支(因为您将来永远不会合并分支)。此外,您可能需要修复在一个客户端上运行的生产版本,同时仍在为该客户端开发下一个版本......分支的一个分支。

如果您在添加新客户时继续这种按客户分公司的策略,情况只会变得更糟。

【讨论】:

  • 是的,但这是一个“旧”应用程序 (html/asp/vb6),现在无法重构“东西”.. 更改可能只是一组自定义页面(如不同图像、文本标签或“微不足道”的东西)。如何在版本控制系统中保留标准版本和这个新版本?
  • 我负责一个基于 VB6 且高度可配置的大型应用程序。尽管我确实理解您可能有一个非常大的代码库要处理,但该技术并没有任何东西使重构成为不可能。您需要诚实地评估重构的(高)成本(专注于您拥有最多定制的领域)是否大于不重构的高成本。只有您知道您的应用程序。请诚实地了解每种替代方案的真实成本。
  • 是的,我知道,但是重构的成本确实很高,不仅是所需的工作量,还因为只有两个人在维护应用程序,因为总是有新的请求出现,而且很多错误要修复。该应用程序已经允许一定程度的定制(主要是在设计中),但我的问题是,如果有人要求一个新的“模块”(一组页面和一些代码),我在哪里将这些新页面保存在 VCS 中?连同所有其他标准页面?我是否仅为这些更改创建一个新的存储库(项目)并集成我提取核心模块并“添加”新模块?
【解决方案3】:

据我所知,您所做的并不是版本控制应该做的。它仅用于跟踪您的源代码,而不是您的分布式产品。对于您关于分支的问题,我认为这个小小的解释可能会有所帮助: -主干是项目的主要开发,这是所有团队成员合作的地方 - 分支是临时开发的地方(是的,你没听错)。在这里,您可以进行实验或弄乱代码,而不会影响其他团队成员 - 标签不过是“命名快照”。在版本控制项目中,快照无处不在,标签是您可以给它们一个更易读的名称的方式 如果您尝试在不处理它们的情况下获得越来越多的分支,那么您的项目将永远增长和增长。我仍然想知道为什么你必须跟踪所有这些。 我再重复一遍,版本控制只是为了在源代码上进行合作,而不是为了分发给多个客户。 希望有所帮助

【讨论】:

  • 是的,我知道版本控制不适用于分发。该应用程序是基于 Web 的,并且自定义可能是对网页、业务逻辑或数据库中的新表的更改。我如何在版本控制系统中管理所有这些更改,确保对一个客户端不会传播到另一个客户端(除非它是故意的。)?
  • 好吧,在那种情况下,我认为它们每个都是一个独立的项目本身(无论它有多小),并且应该有自己的一组主干、分支和标签。您可以为每个项目创建目录。
【解决方案4】:
Feature Branching is a poor man's modular architecture, instead of building systems with the ability to easy swap in and out features at runtime/deploytime they couple themselves to the source control providing this mechanism through manual merging. 

--丹·博达特 -- 来自Martin Fowler

版本控制非常不适合这个工具,因为您想用它来管理版本,而不是客户。

【讨论】:

  • "[U]sing if statements 而不是分支...是一种解决方法,[for] 你的版本控制工具没有做它应该做的事情。" - 乔尔·斯波尔斯基joelonsoftware.com/items/2010/03/17.html
  • 是的:但这似乎是相反情况的一个例子。还是您认为源代码中的所有 if 语句都应该被分支替换?
  • 不,我不认为所有的 if 语句都应该被分支替换。我只是在谈论您使用 if 语句和配置设置作为您没有分支和合并这一事实的解决方法的情况:即,根据您是否在开发中运行来交换模块,测试或生产。
  • 使用 if 语句代替多态是不理解 OO 的一种解决方法。
【解决方案5】:

首先,拥抱分支并学习如何正确使用您的版本控制系统。

我参与了一个项目,他们试图通过标签以您描述的方式管理版本。手动添加/合并针对标签的更改然后应用新标签是某人的工作。这使得每个人都很难保持同步,并且几乎总是由于简单的错误(忘记文件、踩踏更改等)而导致构建损坏。 你基本上是在手动完成分支为你做的事情

关于如何管理不同的客户端定制。除了为每个客户端版本管理分支策略之外,您还应该查看架构并考虑如何管理自定义/差异。

是否可以拆分组件并拥有子项目?一些核心区域可能不会经常更改,并且可以添加到构建中(有点像第三方 jars)。

或者您可以进行基本的构建/安装,然后对自定义进行分层。覆盖自定义文件和/或修改基础文件。

【讨论】:

    【解决方案6】:

    Branches 用于隔离无法在当前相同分支中完成的“开发工作”(此处为一些自定义)。
    由于标签旨在引用“不可变”内容,因此您不应对其进行任何演变。一个简单的:

     cvs tag -r MY_TAG -b MY_BRANCH
    

    从一个分支标签初始化一个分支就足够了。

    应该为每个 UAT(用户验收测试)周期完成这些分支,从您当前的开发开始。然后你可以:

    • 或者尝试将之前为客户演示的之前分支的内容合并到这个新分支中
    • 或直接在新分支中重新实现自定义。
    • 在 UAT 循环完成后保留这些分支。它们不会被修改,但可以作为下一个周期的下一个分支的参考。

    尝试和维护具有自定义功能的分支比在新分支中重新创建所述演变更难:这需要将当前开发合并到该长期存在的分支中,并且您的开发很可能会引入更多与您为客户演示所做的演变相比,对代码的更改更复杂。

    【讨论】:

      猜你喜欢
      • 2010-09-24
      • 2012-03-22
      • 2021-09-18
      • 1970-01-01
      • 1970-01-01
      • 2011-02-21
      • 2013-03-25
      • 2010-12-11
      • 1970-01-01
      相关资源
      最近更新 更多