代码之家  ›  专栏  ›  技术社区  ›  Hoseong Son

多个客户需要多次定制时的Git管理技术

  •  10
  • Hoseong Son  · 技术社区  · 6 年前

    我正在开发一个应用程序项目,该项目将被许多客户使用,他们可能需要单独定制。也就是说,假设我们向1000个客户销售应用程序,我们可能需要在单个程序上进行1000次定制(例如,处理连接、请求等方面的差异)。我认为我们可以分别为每个客户创建一个git分支,但是在一个程序上创建1000个分支?我认为我们无法妥善处理。这不仅仅是我想要的。我想要一个“可持续的”解决方案。我应该如何管理这些源代码? 我知道有“git流”的东西,但我也不知道它是否适合这种情况。

    3 回复  |  直到 6 年前
        1
  •  18
  •   quetzalcoatl    6 年前

    首先,有了1k的定制,我觉得好像出了什么问题。有1k个不同版本的代码,有多少个 开发团队 你需要吗 真正地 支持他们所有人 及时地 ?

    我首先考虑这些“定制”:

    • 真的必须在代码中完成吗?
    • 真的必须进行相同的回购吗?
    • 真的必须由开发人员管理吗?
    • 真的要由你来管理吗?

    对这些问题的任何“否”都会将您的问题重新表述为一个更简单的问题。此外,他们经常一起去。例如,对于“代码中”的“否”,定制似乎主要在配置或数据库中的数据中,这几乎总是意味着对#3的“否”。

    你的目标,作为发展的支持者/管理者/规划者是最后一点。定制是否可以从代码中抛出到配置中,或者在不同的repo中单独的模块/插件,或者是否可以卸载到另一个团队(客户支持团队?)然后你的基本问题就解决了。


    现在,考虑到出于某种原因你不能这样做,那么。。严格Git流的突变是您的朋友。功能分支无处不在。大量使用集成和发布分支。真正严格的流,不是教程化的Git流,而是“扩展”的流。。

    Git流的核心在很大程度上基于功能分支,但在这之后,它是一个单一集成、单一发布的工作流。

    在进一步阅读之前,应该了解Git流是如何工作的。如果没有,那就继续读下去,只有当你觉得自己很清楚的时候,再进一步阅读。

    在“tutorialish”Git流中,每个开发人员都配置:

    • 目标核心主分支机构名称:主
    • 目标下一版本集成分支的名称:开发
    • 要素分支的命名方案:要素/*
    • 发布分支的命名方案:发布/*
    • ..

    对于“1K客户”,此设置存在问题。您可以有大量的功能分支,用于核心改进、新功能、各种自定义等。但是,一旦“完成”它们,它们将转到 develop 这个 共同发展 ,你被抓了。其他人都会得到的。”已完成的客户#1自定义分支最终将通过 发展 进入 release 最终进入 master ,下个月或下一年,所有其他客户也会收到。你不会想要的。

    这证明,不可能有单一的开发,不可能有单一的大师。

    让我们采取另一种方法。


    在“扩展”Git流中,(Git多流,听起来很吸引人,有人吗?),每一个 为客户XYZ工作的开发人员 配置,例如:

    • 目标核心主分支名称:master XYZ
    • 目标下一版本集成分支的名称:develop XYZ
    • 要素分支的命名方案:要素/*
    • 发布分支的命名方案:发布/*
    • ..

    我已经计划他们对主/开发分支使用不同的名称。这意味着对于每个客户,我都有单独的下一版本集成分支,以及当前版本分支的不同版本。

    它给了我们什么?任何开发特性(无论是补丁、定制还是其他)的开发人员都只使用git流。但如果他们成功了 在上下文中 对于客户XYZ,他们将“完成”该功能,并将其集成到专用 develop-XYZ 树枝发布后,它将合并到专用 master-XYZ 树枝不可能“泄漏”功能或自定义项。

    但是,“feature”分支仍然正常。如果在某个时候需要功能#100(最初用于客户ABC)和错误修复#321(最初用于客户DEF),您仍然可以将它们合并到另一个客户,如XYZ, 前提是他们的相关发展差异-/主控-?没有太大区别 ,但这是另一个故事)

    如果听起来不错,好吧,很好,但事实并非如此 那个 美好的有了相当数量的客户,并为他们单独开发/掌握,您很快就会注意到:

    • 如果客户的定制很困难,他们将经常在开发/掌握方面出现分歧,不仅在定制领域,而且在核心代码方面。这将阻碍他们之间未来的功能共享
    • 开发人员 对必须不断更改git流配置(swithc到master FOO,切换到master BAR,master XYZ)或必须保留多个回购副本,配置给不同的客户感到愤怒
    • 拥有单独的开发/主控几乎就像拥有单独的回购协议,但更改通知将向所有人发送垃圾邮件
    • (..)

    这只是开始。其中一些问题可以缓解。第二点可以通过注意git流设置在 .git/config 文件,所以你 无需重新配置gitflow或保留多个repo副本 . 只需编辑文件。或者保留一个git config的副本,然后翻转该文件。或者使用一些$ENV var来表示当前客户。其他解决方法的十分之一。

    接下来是功能。我故意没有考虑命名功能分支 feature/XYZ/ 但还是很简单 feature/ . 功能不必绑定到客户。您可以稍后共享/等。

    接下来,发布。我故意没有考虑命名发布分支 release/XYZ/ . 你可能永远不会分享它们。你可以。然而,我想你已经有了 较好的 为发布分支命名,而不仅仅是在它们前面加上客户名称,如 releases/XYZ 可以。您还需要在那里输入版本号或日期。可能还有一些功能集代码名。我不知道。在这里发明一些东西。

    接下来,核心掌握和发展。对于客户,开发人员正在开发XYZ,掌握XYZ。但你仍然可以有核心 主人 发展 用于改进共享核心代码。没有变化。

    接下来,我说XYZ大师,开发XYZ。但这不一定是这样。你知道 feature/... . 那为什么不呢 masters/XYZ & develops/XYZ ? 当然可以。你甚至可以 XYZ\master XYZ\develop XYZ\feature\ 但是,为什么不像在GitHub上那样进行单独的回购呢?在GitHub上,您可以一个接一个地进行分叉/合并/PR?

    Git Multi-Flow是vanilla Git Flow的扩展,使用后者的命名方案( XYZ \主机 等)您最终会在一次回购中得到类似于多个逻辑回购的东西。一种多租户Git流。。

    所以这是可能的。设置起来并不难。但仍有1000多个分支的主/开发/等集合,由同一组团队处理将是一件痛苦的事。会有错误的。开发人员有时会把事情搞混,他们只是人。根据我的经验,当“大量定制”发生时,几乎只有URL、端口、密码、图像、样式、文本,有时可能是有限的布局更改。也许这里或那里有一个额外的模块。您应该能够在核心代码中处理这一切,并通过配置打开/关闭/配置它。这样,长寿命的“定制分支”(又名master XYZ)的数量将大大减少,但代价是为每个客户部署进行更详细的配置。

    还应跟踪该配置并对其进行版本控制(即再次在Git中)。我希望你已经做了。但它应该位于与代码不同的存储中。这是另一回事。由支持或部署团队管理。提前做好计划。

        2
  •  1
  •   Hendrik M Halkow    6 年前

    为此使用多个存储库。当然,这需要以支持此功能的方式构建应用程序。因此,创建一个核心应用程序,使用所有客户都通用的东西。对于每个客户,创建一个具有自定义项的特定模块。当然,它们进入不同的存储库。 如果客户端请求的功能需要对核心模块进行特定于客户的更改,请重构应用程序,以便在核心模块之外进行自定义。如果时间有问题,请使用特定于客户机的分支,并进行挑选或合并。这是可以的,只要是在短时间内。 我们在我的一位客户身上成功地使用了这种方法,他也面临着同样的挑战。

        3
  •  1
  •   Efrain    4 年前

    简短回答:不要使用git回购来模拟这种需求。

    不幸的是,我建议将不同客户的所有内容都进行配置。这样,您可以向每个客户部署相同的版本,并且只有一个发布渠道。

    我们公司也有类似的情况,这是我随着时间的推移得出的结论。缺点是这些配置可能会变得杂乱无章,使代码变得复杂,并且您的系统不太确定/难以测试。问题是,在编码和建模方面,需要正确执行。我认为最重要的是对产品或领域有丰富的经验,这样就可以知道应该如何对哪些设置进行建模,如果客户想要一些奇怪的东西,甚至可以推回。

    以下是我的可配置性分层列表(从最佳到最差):

    1. 使用配置的持久层(DB)建模

      允许用户通过UI/ConfigTools进行自助服务,但需要付出大量努力才能实现

    2. 使用动态组合的模块/包/服务

      需要复杂的体系结构和部署—通常非常/太复杂

    3. 使用配置文件

      可能会成为1k客户的噩梦-简单但扩展性不太好(例如,添加新的配置设置时)

    4. 硬编码(例如依赖注入)

      错误:要求每个客户都有一个分支机构/回购,这实际上并不可行

    基本上,每个客户端都有一个共同的核心,每个客户端都有一个增量。问题是你在哪里保留和构建这个三角洲。如何保存、显示和建模。这就是为什么#1是最好的:配置保存在已部署实例本身中,并随每个版本一起迁移。这是一个纯运行时的东西(但为了安全起见可以备份)。 #2和#3属于同一个级别,两者都不理想,当你有超过20个设置/差异时会变得混乱。