供应商分支在Git

Sam*_*ody 29 git version-control branch vendor-branch

Git项目中包含第二个项目,其内容正在独立工作.

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

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

我被告知这个解决方案在SVN世界中被称为"供应商分支",并且它在Git中是如此简单,以至于甚至不需要寻址.网上有很多半生不熟的教程.

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

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

请不要向我解释我应该如何使用子模块或子树合并甚至SVN:Externals.这个线程是以下SO线程的产物,如果在那里错过了某些东西,请把它贴在那里.这个主题试图了解如何供应商分支机构,以及更长,更清晰,更笨拙的解释,我收到的解释会更快乐.

Von*_*onC 35

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

只是一个想法; 你要:

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

这两种方法不兼容:

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

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

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


samgoody补充道:

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

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

这一切都是针对粒度问题做的:

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

samgoody补充道:

原始线程列出了子模块的问题 - 主要是GitHub的下载不包括它们(对我来说至关重要),并且它们被卡在特定的提交上.

我不确定最近GitHub的下载是一个问题:" 指南:使用子模块开发 "一文确实提到:

最重要的是:当您注册子模块的公共克隆URL时,克隆您的my-awesome-frameworkfork的人在下拉my-fantastic-plugin子模块时没有任何问题.命令

$ gh submodule init
$ gh submodule update
Run Code Online (Sandbox Code Playgroud)

将子模块拉入当前存储库.

至于"他们陷入特定的提交":这是子模块的全部要点,允许您使用配置(组件的标记版本列表)而不是最新的可能不稳定的文件集.

samgoody提到:

我需要避免使用子树和子模块(请参阅问题),如果方法合理,我宁愿解决这个需求而不要过多争论

您的要求是完全合法的,我不想判断其理由:我以前的答案只是提供更大的背景,并试图说明通用SCM工具通常可用的选项.

子树合并应该是这里的答案,但是意味着仅合并为主项目提交的文件的提交,而不是为子项目提交的提交.如果你可以管理那种部分合并,我认为这是正确的道路.

然而,我没有看到一个本机Git方法来做你想要的不使用子树 - 合并或子模块.
我希望真正的Git大师会在这里发布更充分的答案.

  • @JW。在我过去使用ClearCase的经历中,我第一次遇到了这些概念:http://stackoverflow.com/a/1766662/6309 (2认同)

Pau*_*aul 8

在我回到山上之前,我终于有几个小时进入网.我们会看看我是否有任何事情可以帮助您明确自己的情况.

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

  1. 就像VonC(通常非常认真地考虑事情)一样,我不认为Git 完全符合您的要求.和他一样,我认为使用子树合并模式是最接近的.我不是Git大师,但我成功地将Git扩展到了广泛的需求.也许Git不符合您的需求:

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

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

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

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

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

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

  • 就我个人而言 - ..你说:"我不是一个Git大师" - 我注意到,你的答案是几乎在网站上每一个相关的Git Q"接受的答案.我非常感谢你的帮助..."VonC(通常认为事情非常彻底)" - 我应该这么认为.如果有人在世界专家的贡献下获得25,000+积分,那该怎么办?我很敬畏!我也很感谢他的帮助.你们好棒.现在,如果我能让这个工作...... :) (4认同)