Git项目内有第二个项目,其内容正在独立处理。
子模块不能用于较小的子模块,因为当用户尝试克隆或下载“父”时,甚至必须包含子项目。
不能使用子树合并,因为正在积极开发子项目,并且子树合并使得将这些更新合并回原始项目非常困难。
我被告知该解决方案在SVN世界中被称为“供应商分支”,并且它在Git中完成,因此甚至不需要寻址。 在网上有很多半生不熟的教程。
尽管如此,我似乎无法让它发挥作用。
有人可以(非常好吗?)解释我如何创建一个结构,其中一个项目存在于另一个项目中,并且两者都可以从同一个工作目录开发和更新。 理想情况下[或者更确切地说:如果不支持则非常重要],当客户端尝试下载“父”项目时,应该自动给予子项目的最新版本。
请不要向我解释我应该如何使用子模块或子树合并甚至SVN:Externals。这个帖子是the following SO thread的产物,如果在那里遗漏了某些东西,请把它发布在那里。这个帖子正试图搞定 了解如何供应商的分支机构,以及更长,更清晰,更笨拙的解释,我收到的解释会更快乐。
答案 0 :(得分:33)
我认为子模块是“供应商分支”的方法 以下是你应该如何使用submod ......嗯,开个玩笑。
只是一个想法;你想要的:
这两种方法不兼容:
我喜欢第二种方法,因为大多数时候,当你有一个项目和一个子项目时,他们的生命周期是不同的(它们不是以相同的节奏开发的,没有标记在一起同时,也没有同名)。
在你的问题中真正阻止这种方法(“基于组件的”)的是“两者都可以从同一工作目录开发和更新”部分。
我真的会敦促你重新考虑这个要求,因为大多数IDE完全有能力处理多个“源”目录,子项目开发可以在自己的专用环境中完成。
想象一下Joomla和ModX的eMap插件。插件和Joomla特定代码(它是Joomla的一部分,而不是eMap)都是在插件位于Joomla中时开发的。所有路径都是相对的,结构是刚性的,它们必须分布在一起 - 即使每个项目都有自己的生命周期。
如果我理解正确,那么您处于一种配置,其中开发环境(您正在处理的文件集)与分发环境完全相同(在发布平台上复制相同的文件集)
这完成了一个粒度问题:
原始线程列出了子模块的问题 - 主要是GitHub的下载不包含它们(对我来说至关重要),并且它们被卡在特定的提交上。
我不确定最近GitHub的下载是一个问题:“Guides: Developing with Submodules”文章的确提到:
最重要的是:由于您已经注册了子模块的公共克隆URL,因此克隆您的
my-awesome-framework
分叉的人在下载my-fantastic-plugin
子模块时没有任何问题。命令
$ gh submodule init
$ gh submodule update
将子模块拉入当前存储库。
至于“他们陷入特定的提交”:这是子模块的全部要点,允许您使用配置(组件的标记版本列表)而不是最新的潜在不稳定文件集。
samgoody提到:
我需要避免使用子树和子模块(请参阅问题),如果方法合理,我宁愿解决这个问题而不要过多争论
您的要求是完全合法的,我不想判断其理由:我之前的答案只是提供更大的背景,并尝试说明通用SCM工具通常可用的选项。
子树合并应该是这里的答案,但是意味着只合并为主项目的文件提交,而不是为子项目提交。如果你可以管理那种部分合并,我认为这是正确的道路。
然而,我没有看到一个本机Git方法来做你想要的不使用子树 - 合并或子模块的东西。
我希望真正的Git大师会在这里发布更充分的答案。
答案 1 :(得分:8)
在我回到山区之前,我终于有几个小时的时间进入网络了。我们会看看是否有任何事情可以帮助您清楚了解情况。
我(可能是过度简化)的理解是你有(非现场)供应商为你的项目开发插件,你的(内部)团队正在使用外部源框架为你的主项目开发代码。供应商不会对您的代码进行更改,也可能不需要您的前沿开发,但确实需要您的稳定代码来开发和测试他们的工作。您的团队不会对框架进行更改,但有时会对插件进行更改。
和VonC一样(通常认为事情非常彻底)我不认为Git有一个完美的符合您的要求。和他一样,我认为使用子树合并模式是最接近的。我不是Git大师,但我成功地将Git扩展到了广泛的需求。也许Git不能满足你的需求:
SVN会让你在一个内部有多个回购,这对你来说很重要。我认为这意味着使用外部或供应商分支模式接近你想要的。
Mercurial有一个扩展名Forest, 使用嵌套的repos,这似乎更适合你的心智模型。我在15个月前选择了Git而不是Mercurial,但是HG很稳定,并且在许多用途中我认为它与Git相当。我不知道扩展是多么稳定。
如果我在你的情况下,我会使用两个Git回购 - 一个用于插件,一个用于MainProject。供应商将在插件仓库中进行开发,并且有一个发布分支,他们将插件的当前版本拉入其中,而不需要其他开发环境。该分支将作为供应商分支被拉入MainProject仓库,然后合并到您的主要开发分支中。 当您的团队更改插件时,他们会在主开发分支的功能分支中进行开发,并将其作为补丁提交给供应商仓库。这为您提供了一个非常干净的工作流程,相对容易设置和学习,同时保持发展历史的隔离。
我不是要争论,而只是说这是Git最适合我理解你的情况。设置此方法的最简单方法是使用子树合并,但这不会在两个方向上进行更改,这是我对使用该模式的反对意见。
如果您的团队真的积极参与插件开发,或者您真的希望将项目和插件的开发历史集成在一个Git仓库中,那么只需使用一个Git仓库。您可以不时地将供应商记录的插件及其历史记录提取为explained here。这可能比你想要的封装少,但Git不是为封装而设计的--Git的数据结构基于跟踪整个项目中的变化。
也许我误解了你的情况,但没有一个适用。如果是这样,我道歉。感谢您和VonC制定的详细信息,这些信息填补了我在尝试理解您的问题时遇到的许多漏洞。
答案 2 :(得分:0)