供应商分支在Git

一个Git项目里面有一个独立工作的第二个项目。

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

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

我已经被告知,这个解决scheme在SVN世界中被称为“Vendor Branches”,并且它在Git中简单地完成,甚至不需要处理。 “网”上有不完整的教程。

尽pipe如此,我似乎无法得到它的工作。

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

请不要向我解释我应该如何使用子模块或子树合并,甚至是SVN:Externals。 这个线程是以下SO线程的产物,如果在那里丢失了某些东西,请把它张贴在那里 。 这个线程试图了解如何供应商的分支机构,越来越明确,越来越愚蠢的解释,我收到了我会更快乐。

我认为子模块是“供应商分支”的一种方式。
这里是你应该如何使用submod …嗯,只是开玩笑。

只是一个想法; 你要:

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

这两种方法不兼容:

  • 第一个策略与子树合并兼容:您既在项目又在子项目中工作。
  • 第二个与子模块一起使用,但子模块用于定义一个configuration (需要工作的标签列表):与svn:externals不同,每个git子模块都被固定到一个特定的提交ID,这就是允许你定义configuration (如S C M:“软件configurationpipe理”)

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

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


samgoody补充说:

想象一下,Joomla和ModX的eMap插件。 插件和Joomla特定的代码(它是Joomla的一部分,而不是eMap)是在Joomla内部插件的情况下开发的。 所有path都是相对的,结构是僵化的,它们必须一起分配 – 即使每个项目都有自己的生命周期。

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

这一切都是在一个粒度问题上完成的:

  • 如果两套文件不能彼此存在,那么它们应该被看作是一个大项目(和子树合并),但是迫使它们被标记和合并为一个。 如果一个依赖于另一个(可以单独开发),那么他们应该在自己的Git仓库和项目中,第一个依赖于第二个作为子模块的具体提交:如果子模块是在第一个组件的右侧子树中定义,所有相对path都受到尊重。

samgoody补充说:

最初的线程列出了子模块的问题 – 主要是GitHub的下载不包括它们(对我来说至关重要),并且它们被困在一个特定的提交中。

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

最重要的是:克隆你的my-awesome-framework分支的人将没有问题拉下你的my-fantastic-plugin子模块,因为你已经注册了子模块的公共克隆URL。 命令

 $ gh submodule init $ gh submodule update 

将子模块拉入当前的存储库。

至于“他们卡在一个特定的提交”:这是一个子模块的所有点,允许您使用一个configuration (组件的标签版本列表),而不是最新的潜在不稳定的文件集。

samgoody提到:

我需要避免使用子树和子模块(参见问题),而且如果方法是有道理的,宁愿处理这个需求而不要争辩太多

你的要求是完全合法的,我不想判断它的理由:我以前的答案只是在这里提供一个更大的上下文,并试图说明一般的SCM工具通常可用的选项。

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

我没有看到一个本地的Git方式来做你想做的事,不使用子树合并或子模块。
我希望一个真正的Git大师会在这里发布一个更合适的答案。

在我回到山上之前,我终于有了几个小时的上网时间。 我们会看看是否有任何东西可以为您的情况做出贡献。

我的(可能是过于简单的)理解是你有(厂外)供应商为你的项目开发插件,你的(内部)团队正在使用外部源框架为你的主项目开发代码。 供应商不会对您的代码进行更改,也可能不需要您的开发优势,但确实需要稳定的代码来开发和testing他们的工作。 您的团队不会对框架进行更改,但有时会对插件做出更改。

  1. 就像VonC(他通常认为事情是非常彻底的)我不认为Git 完全适合你的要求。 像他一样,我认为使用子树合并模式是最合适的。 我不是一个Git大师,但是我已经成功地将Git屈从于广泛的需求。 也许Git不符合你的需求:

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

    • Mercurial扩展名为Forest,使用嵌套的回购,这似乎更适合你的心智模式。 我在15个月前select了Git而不是Mercurial,但是HG很稳定,而且对于很多用途我认为它可以和Git相媲美。 我不知道扩展是多么稳定。

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

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

  3. 如果您的团队真的积极参与插件开发,或者您真的想将项目和插件的开发历史集成到一个Git仓库中,那么只需使用一个Git仓库。 您可以随时解释这个插件及其供应商logging的历史logging。 这可能会让你的封装比你打算的less,但Git并不是为封装而devise的 – Git的数据结构是基于跟踪整个项目中的变化。

也许我误解了你的情况,这些都不适用。 如果是的话,我表示歉意。 感谢您和VonC制定的细节,这些细节填补了我原本试图了解您的问题的许多漏洞。

Interesting Posts