我认为子模块是“供应商分支”的必经之路。
以下是您应该如何使用 submod... 嗯,开个玩笑。
只是一个想法; 你要:
- 在同一目录中开发主项目和子项目(这称为“系统方法”:您开发、标记和合并所有系统)
- 或将您的子项目视为“供应商分支”(这是一个允许您访问供应商外部组件或“文件集”的明确定义版本的分支,并且仅使用新的版本该外部组件的每个版本:这称为“组件方法”,所有系统都被视为自行开发的独立组件的集合)
这两种方法不兼容:
- 第一个策略与子树合并兼容:您同时在项目和子项目上工作。
- 第二个用于子模块,但子模块用于定义配置(您需要工作的标记列表):每个 git 子模块,与 svn:externals 不同,都固定到特定的提交 id,这就是允许您定义配置(如 S C M:“软件配置管理”)
我喜欢第二种方法,因为大多数时候,当你有一个项目和一个子项目时,它们的生命周期是不同的(它们的开发节奏不同,没有同时标记在一起,也没有同名) .
在您的问题中真正阻止这种方法(“基于组件”)的是“两者都可以从同一个工作目录中开发和更新”部分。
我真的敦促您重新考虑该要求,因为大多数 IDE 完全能够处理多个“源”目录,并且子项目开发可以在其自己的专用环境中完成。
samgoody 补充道:
想象一下适用于 Joomla 和 ModX 的 eMap 插件。插件和特定于 Joomla 的代码(它是 Joomla 的一部分,而不是 eMap 的一部分)都是在插件位于 Joomla 内部时开发的。所有路径都是相对的,结构是刚性的,它们必须分布在一起——即使每个项目都有自己的生命周期。
如果我理解正确,您处于开发环境(您正在处理的文件集)与分发环境(在发布平台上复制相同的文件集)完全相同的配置中
这一切都是为了一个粒度问题:
- 如果两组文件不能单独存在,那么它们应该被视为一个大项目(和子树合并),但这会迫使它们被标记并合并为一个。- 如果一个依赖于另一个(可以单独开发),那么它们应该在自己的 Git 存储库和项目中,第一个依赖于第二个作为子模块的特定提交:如果子模块是在第一个组件的右子树中定义,所有相对路径都受到尊重。
samgoody 补充道:
原始线程列出了子模块的问题 - 主要是 GitHub 的下载不包括它们(对我来说很重要)并且它们卡在特定的提交上。
我不确定 GitHub 的下载最近是否存在问题:“指南:使用子模块开发”文章确实提到:
最重要的是:克隆你的my-awesome-framework
fork 的人将没有问题拉下你的my-fantastic-plugin
子模块,因为你已经为子模块注册了公共克隆 URL。命令
$ gh submodule init
$ gh submodule update
将子模块拉入当前存储库。
至于“他们卡在特定的提交上”:这是子模块的全部要点,允许您使用配置(组件的标记版本列表)而不是最新的可能不稳定的文件集。
samgoody 提到:
我需要避免使用子树和子模块(请参阅问题),如果方法合理,我宁愿解决这个需求而不争论太多
您的要求是完全合理的,我不想评判其合理性:我之前的回答只是为了提供更大的上下文并尝试说明通用 SCM 工具通常可用的选项。
子树合并应该是这里的答案,但意味着只合并为主项目的文件提交,而不是子项目的提交。如果您可以管理这种部分合并,我认为这是正确的道路。
但是,我看不到不使用子树合并或子模块的本地 Git 方式来做你想做的事。
我希望真正的 Git 大师会在这里发布更充分的答案。