在多个客户的Web项目中使用git

时间:2012-08-11 14:12:17

标签: git project web-deployment

使用git在几个客户项目中使用小型随机更新对版本控制Web项目提出了更好的建议吗?

我想将git用于Web项目的版本控制。与几乎所有其他提案的主要区别在于,这是一个使用HTML,JavaScript和一些PHP文件的Web项目 - 没有中央库被一个或多个程序使用,就像典型的Linux软件包中一样。

我所有不同的网络项目都是针对不同的客户,基于相同的平台文件,我估计80%的文件是相同的(称为平台),20%是针对不同的客户进行修改以满足他们的需求。这里的问题是,我不知道我们需要客户更新哪些文件 - 详细地说每个客户都不同。

最好将平台特定文件保存在一个目录中,并将这些文件与客户特定文件重叠在另一个目录中。为了用git解决这个问题,到目前为止我没有找到任何好处:

  • git submodule (与提议的here一样) 通常设计为使供应商开发的库的源接近链接它的程序。因此问题是平台和客户文件位于不同的目录中,因此我必须在部署期间将它们混合以创建Web服务器的文件。此外,我必须手动保持目录树同步,这对于10个目录深度层次结构来说将是很多工作。一般来说,很多帖子抱怨使用子模块的大量管理工作,看起来有点矫枉过正。
  • git子树(与提议的here一样) 似乎比子模块更简单但是遇到了不同目录的相同问题,所以我还需要保持dir结构同步并在部署期间混合文件。此外,很难从客户回购推动平台变更。
  • GitSlave (与提议的here一样) 我不确定这对我是否有益。它允许保持几个git repos同步,也许它有助于同步平台的dir结构,但我无法相信它
  • 在不同目录中的平台和客户文件之间重构(如this讨论的结果) 我认为,对于我的客户和Web项目使用的技术,这根本不可能。对于一个客户,此页面需要更新,另一个页面需要更新。即使在引入PHP框架时,客户特定的更改也会分布在整个树中。
  • 结帐(也像this在上次发帖中讨论的那样提议) 这看起来非常简单和有前途,缺点是所有客户特定文件都在git之外(因此在版本控制之外)。此外,如果文件在平台和客户中更新,git pull会失败 - 它会中止,因此无法使用
  • 供应商分支(如已重新开始here) 据我所知,分支机构被合并回来,而不是针对我的客户特定补丁。这些分支将始终是开放的,仅在从平台(主)向客户更新后合并。这将导致一个巨大的回购保留所有客户和平台信息 - 而不是处理回购的git方式。
  • 部署期间混合。因此,一种非常务实的方法是将平台文件保存在一个仓库中,客户文件也保存在专用的仓库中。在将文件部署到Web服务器期间,它可以首先编写所有平台文件,而不是通过特定于平台的文件覆盖其中一些文件。混合发生在Web服务器目录中很晚。这也有一个缺点,即每个客户的目录结构必须手动保持与平台结构同步 - 否则部署将太复杂。

这里最好的方法是什么?

2 个答案:

答案 0 :(得分:4)

TL; DR

这实际上是一个架构设计问题,而不是源代码管理问题。然而,这是一个常见的有趣的问题,所以我提供了一些关于如何解决架构问题的一般性建议。

不是真正的Git问题

问题不在于Git。问题在于,您没有充分区分保持不变的内容与客户之间的变化。一旦确定了正确的设计模式,适当的源控制模型就会变得更加明显。

考虑一下Russ Olsen的这句话:

  

[分开]可能会从可能保持不变的事物中改变的事物。如果您可以确定系统设计的哪些方面可能会发生变化,则可以将这些位与更稳定的部分隔离开来。

     

奥尔森,拉斯(2007-12-10)。 Ruby中的设计模式(Kindle Locations 586-588)。培生教育(美国)。 Kindle版。

一些重构建议

我不太了解您的应用程序以提供具体建议,但一般 Web项目可以从几种不同的设计模式中受益。模板,复合或原型模式可能都适用,但有时讨论模式会使问题更容易混淆。

没有特别的顺序,这就是我个人所做的事情:

  1. 在视图层,严重依赖模板。大量使用布局,包含或部分,以便您可以更轻松地组合表示层对象。
  2. 大量使用客户特定的配置文件(我更喜欢YAML用于此目的),以便在不修改核心代码的情况下更轻松地进行自定义。
  3. 在模型和控制器层,选择一些合适的structural patterns,以允许您的对象根据客户特定的配置文件进行多态操作。鸭子打字是你的朋友!
  4. 使用基于主机名或域的内省,为每个客户端启用多态行为。
  5. 使用Git的后续步骤

    一旦您重构了应用程序以最大限度地减少客户之间的更改,您可能会发现除非您试图隐藏每个客户端的多态代码,否则根本不需要保持代码分离。如果是这种情况,您当然可以在那时调查子模块或单独的分支,但没有分支之间重复的负担。

    符号链接是你的朋友,太

    最后,如果您发现可以将更改隔离到几个子目录中,Git支持符号链接。您可以在开发分支的每个客户端子目录中简单地拥有所有不同的代码,并将文件符号链接到每个客户端版本分支上的正确位置。您甚至可以使用一些shell脚本或在自动部署期间自动执行此操作。

    这将您的所有开发代码保存在一个位置,以便于比较和重构(例如开发分支),但确保真正 的代码需要针对每个版本进行不同需要当你把它投入生产时。

答案 1 :(得分:2)

由于您为每个供应商定制解决方案的性质,供应商分支最有意义。最好的方法是放弃这个并开发multi-tenant application