供应商分支在Git

时间:2009-04-20 19:33:40

标签: git version-control branch vendor-branch

Git项目内有第二个项目,其内容正在独立处理。

子模块不能用于较小的子模块,因为当用户尝试克隆或下载“父”时,甚至必须包含子项目。

不能使用子树合并,因为正在积极开发子项目,并且子树合并使得将这些更新合并回原始项目非常困难。

我被告知该解决方案在SVN世界中被称为“供应商分支”,并且它在Git中完成,因此甚至不需要寻址。 在网上有很多半生不熟的教程。

尽管如此,我似乎无法让它发挥作用。

有人可以(非常好吗?)解释我如何创建一个结构,其中一个项目存在于另一个项目中,并且两者都可以从同一个工作目录开发和更新。 理想情况下[或者更确切地说:如果不支持则非常重要],当客户端尝试下载“父”项目时,应该自动给予子项目的最新版本

请不要向我解释我应该如何使用子模块或子树合并甚至SVN:Externals。这个帖子是the following SO thread的产物,如果在那里遗漏了某些东西,请把它发布在那里。这个帖子正试图搞定 了解如何供应商的分支机构,以及更长,更清晰,更笨拙的解释,我收到的解释会更快乐。

3 个答案:

答案 0 :(得分:33)

我认为子模块是“供应商分支”的方法 以下是你应该如何使用submod ......嗯,开个玩笑。

只是一个想法;你想要的:

  • 在同一目录中开发主项目和子项目(称为“系统方法”:您开发,标记和合并所有系统)
  • 或将您的子项目视为“供应商分支”(这是一个分支,允许您访问定义良好的供应商外部组件版本 - 或“文件集” - ,并且仅更新新版本的外部组件的每个版本:称为“组件方法”,所有系统都被视为一组独立开发的组件。

这两种方法不兼容:

  • 第一个策略与子树合并兼容:您正在项目和子项目中工作。
  • 第二个用于子模块,但子模块用于定义配置(需要工作的标签列表):每个git子模块与svn:externals不同,固定到特定的模块提交ID,这就是允许您定义配置的原因(如在 C M中:“软件配置管理”)

我喜欢第二种方法,因为大多数时候,当你有一个项目和一个子项目时,他们的生命周期是不同的(它们不是以相同的节奏开发的,没有标记在一起同时,也没有同名)。

在你的问题中真正阻止这种方法(“基于组件的”)的是“两者都可以从同一工作目录开发和更新”部分。
我真的会敦促你重新考虑这个要求,因为大多数IDE完全有能力处理多个“源”目录,子项目开发可以在自己的专用环境中完成。


samgoody补充道:

  

想象一下Joomla和ModX的eMap插件。插件和Joomla特定代码(它是Joomla的一部分,而不是eMap)都是在插件位于Joomla中时开发的。所有路径都是相对的,结构是刚性的,它们必须分布在一起 - 即使每个项目都有自己的生命周期。

如果我理解正确,那么您处于一种配置,其中开发环境(您正在处理的文件集)与分发环境完全相同(在发布平台上复制相同的文件集)

这完成了一个粒度问题:

  • 如果两个文件集都不能存在,那么它们应该被视为一个大项目(和子树合并),但这会强制它们被标记并合并为一个。 - 如果一个取决于另一个(可以单独开发),那么它们应该在他们自己的Git存储库和项目中,第一个取决于第二个作为子模块的特定提交:如果子模块是在第一个组件的右子树中定义,所有相对路径都受到尊重。

samgoody补充道:

  

原始线程列出了子模块的问题 - 主要是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)

在我回到山区之前,我终于有几个小时的时间进入网络了。我们会看看是否有任何事情可以帮助您清楚了解情况。

我(可能是过度简化)的理解是你有(非现场)供应商为你的项目开发插件,你的(内部)团队正在使用外部源框架为你的主项目开发代码。供应商不会对您的代码进行更改,也可能不需要您的前沿开发,但确实需要您的稳定代码来开发和测试他们的工作。您的团队不会对框架进行更改,但有时会对插件进行更改。

  1. 和VonC一样(通常认为事情非常彻底)我不认为Git有一个完美的符合您的要求。和他一样,我认为使用子树合并模式是最接近的。我不是Git大师,但我成功地将Git扩展到了广泛的需求。也许Git不能满足你的需求:

    • SVN会让你在一个内部有多个回购,这对你来说很重要。我认为这意味着使用外部或供应商分支模式接近你想要的。

    • Mercurial有一个扩展名Forest, 使用嵌套的repos,这似乎更适合你的心智模型。我在15个月前选择了Git而不是Mercurial,但是HG很稳定,并且在许多用途中我认为它与Git相当。我不知道扩展是多么稳定。

  2. 如果我在你的情况下,我会使用两个Git回购 - 一个用于插件,一个用于MainProject。供应商将在插件仓库中进行开发,并且有一个发布分支,他们将插件的当前版本拉入其中,而不需要其他开发环境。该分支将作为供应商分支被拉入MainProject仓库,然后合并到您的主要开发分支中。 当您的团队更改插件时,他们会在主开发分支的功能分支中进行开发,并将其作为补丁提交给供应商仓库。这为您提供了一个非常干净的工作流程,相对容易设置和学习,同时保持发展历史的隔离。

    我不是要争论,而只是说这是Git最适合我理解你的情况。设置此方法的最简单方法是使用子树合并,但这不会在两个方向上进行更改,这是我对使用该模式的反对意见。

  3. 如果您的团队真的积极参与插件开发,或者您真的希望将项目和插件的开发历史集成在一个Git仓库中,那么只需使用一个Git仓库。您可以不时地将供应商记录的插件及其历史记录提取为explained here。这可能比你想要的封装少,但Git不是为封装而设计的--Git的数据结构基于跟踪整个项目中的变化。

  4. 也许我误解了你的情况,但没有一个适用。如果是这样,我道歉。感谢您和VonC制定的详细信息,这些信息填补了我在尝试理解您的问题时遇到的许多漏洞。

答案 2 :(得分:0)

如果你只是寻找原始问题的标题:

git的供应商分支模式的一个很好的模板是

https://www.roe.ch/Git_Reference

部分供应商分支模式