【问题标题】:Best Practice for Git Repositories with multiple projects in traditional n-tier design传统 n 层设计中具有多个项目的 Git 存储库的最佳实践
【发布时间】:2011-04-01 14:26:07
【问题描述】:

我正在从集中式 SCM 系统切换到 GIT。好的,我承认哪一个,它是 Visual SourceSafe。因此,除了克服 Git 命令和工作流程的学习曲线之外,我目前面临的最大问题是如何将我们当前的存储库迁移到 Git,以了解单个或多个存储库的某种风格。

我已经看到以各种方式提出这个问题,但通常只是基本的......“我有想要共享一些较低级别库的应用程序”并且预设响应始终是“使用单独的存储库”和/或“使用 Git 子模块”,而没有太多解释何时/为什么应该使用此模式(它克服了什么,消除了什么?)从我迄今为止对 Git 的有限知识/阅读来看,似乎子模块可能有自己的恶魔战斗,尤其是对于 Git 新手。

然而,我还没有看到有人公然问过,“当你有传统的 n 层开发(UI、业务、数据,然后是共享工具),其中每一层都是自己的项目时,你应该使用一个或多个存储库?”我不清楚,因为几乎总是,当添加新的“功能”时,代码更改会波及每一层。

为了使 Git 的问题复杂化,我们在“框架”中复制了这些层,以便从开发人员的角度制作更易于管理的项目/组件。出于本次讨论的目的,我们将这些项目/层的集合称为“Tahiti”,它代表了一个完整的“产品”。

我们设置的最后一个“层”是添加在大溪地进行定制/扩展的客户网站/项目。在文件夹结构中表示它可能最好如下所示:

/Clients
  /Client1
  /Client2

/UI Layer
  /CoreWebsite (views/models/etc)
  /WebsiteHelper (contains 'web' helpers appropriate for any website)
  /Tahiti.WebsiteHelpers (contains 'web' helpers only appropriate for Tahiti sites)

/BusinessLayer (logic projects for different 'frameworks')
  /Framework1.Business
  /Framework2.Business

/DataLayer
  /Framework1.Data
  /Framework2.Data

/Core (projects that are shared tools useable by any project/layer)
  /SharedLib1
  /SharedLib2

在解释了我们如何通过多个项目扩展传统的 n 层设计之后,我正在寻找有关您在类似情况下做出何种决定的任何经验(即使是简单的 UI、业务、数据分离)您使用的所有内容)以及由于您的决定而变得更容易/更难的事情。我对子模块如何有点痛苦的初步阅读是正确的吗?痛苦大于好处?

我的直觉是为 Tahiti 提供一个存储库(除“客户项目”外的所有项目),然后为每个客户创建一个存储库。我猜的整个大溪地资源必须是

  • 在我看来,在 Git 中,您希望跟踪“功能”与单个“项目/文件”的历史记录,即使我们的项目分离,一个“功能”也将始终跨越多个项目。
  • 核心网站中编码的“功能”几乎总是会对核心网站和“框架”的所有项目(即 CoreWebsite、Framework1.Business、Framework1.Data)的影响最小化
  • 一个功能可以轻松跨多个框架(我想说我们实现的功能中有 10% 会跨框架 - CoreWebsite、Framework1.Business、Framework1.Data、Framework2.Business、Framework2.Data)
  • 以类似的方式,一项功能可能需要更改 1 个或多个 SharedLib 项目和/或“UI 网站助手”项目。
  • 对客户自定义代码的更改几乎总是只在其存储库本地进行,不需要跟踪对其他组件的更改以查看“整个功能更改集”是什么。
  • 鉴于一项功能跨越项目以查看整个范围,如果每个项目都是其自己的存储库,那么尝试跨存储库分析 *所有* 代码更改似乎会很痛苦?

提前致谢。

【问题讨论】:

  • 我们遇到了完全相同的问题,正在查看git subtree 来处理这些依赖关系。

标签: visual-studio git visual-sourcesafe repository repository-design


【解决方案1】:

大多数人建议创建单独的存储库的原因是因为它将更改和更改集分开。如果有人对客户端项目进行了更改(您说这不会真正影响其他人),那么某人没有理由更新整个代码库。他们可以简单地从他们关心的项目中获取更改。

Git 子模块就像 Subversion 中的 Externals。您可以设置您的 git 存储库,以便每个存储库都是一个单独的层,然后使用子模块将所需的项目包含在您拥有的各种层次结构中。

如果例如:

/Core -- It's own git repository that contains it's base files (as you had outlined)
  /SharedLib1
  /SharedLib2

/UI Layer -- Own git repository 
  /CoreWebsite
  /WebsiteHelper
  /Tahiti.WebsiteHelpers
  /Core -- Git Submodule to the /Core repository
    /SharedLib1
    /SharedLib2

这可确保对 /Core 存储库的任何更新都被带入 UI 层存储库。这也意味着如果您必须更新您的共享库,您不必跨 5-6 个项目进行更新。

【讨论】:

  • “这也意味着如果您必须更新您的共享库,您不必跨 5-6 个项目进行更新”...您的意思是我可以拉取 Core而不是所有项目?在您的示例中,/Core 物理文件夹是否真的位于硬盘上的 /UI 层下(这是否也位于 /Core 根目录下)?如果有(并且是子模块),它是否有自己的 .git 文件夹?
  • 是的,/Core 将位于 /"UI Layer" 下并拥有自己的 .git 文件夹。如果您不想,您不必将 /Core 放在文件系统上它自己的文件夹中,如果您需要更改 Core,您可以在 /UI_Layer/Core 文件夹中进行,提交并推送到 /Core从那里回购。
  • 但是当您在系统上的另一个文件夹中有/Core 时,例如因为它被/UI Layer 2 使用,您必须拉另一个文件夹才能看到更改...@Koby,也许在你的答案中包含一个提示;)
猜你喜欢
  • 2015-09-21
  • 1970-01-01
  • 2021-09-20
  • 2014-05-23
  • 2014-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-26
相关资源
最近更新 更多