Git 中的供应商分支

发布于 2024-07-17 14:35:40 字数 656 浏览 11 评论 0原文

Git 项目中包含第二个项目,其内容是独立处理的。

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

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

我得知该解决方案在 SVN 世界中被称为“供应商分支”,并且它在 Git 中完成得非常简单,甚至不需要寻址。 网络上有大量半生不熟的教程。

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

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

请不要向我解释应该如何使用子模块或子树合并甚至 SVN:Externals。 该线程是以下SO线程的产物,如果有的话错过了那里,请务必将其发布到那里。 该线程正在尝试获取 了解如何供应商分支,并且我收到的解释越长、越清晰、越虚拟,我就会越高兴。

A Git project has within it a second project whose content is being worked on independently.

Submodules cannot be used for the smaller, as even the subproject must be included when users attempt to clone or download the 'parent'.

Subtree-merging cannot be used, as the subproject is being actively developed, and subtree merging makes it very difficult to merge those updates back into the original project.

I have been informed that the solution is known in the SVN world as "Vendor Branches", and that it is so simply done in Git so as to not even need addressing.
Half-baked tutorials abound on the 'net.

Nonetheless, I cannot seem to get it to work.

Can someone please (pretty please?) explain how I can create a structure whereby one project exists within another, and both can be developed and updated from the same working directory.
Ideally [or rather: it is quite important, if unsupported] that when a client attempts to download the 'parent' project, that he should be given the latest version of the subproject automatically.

Please do NOT explain to me how I should use submodules or subtree-merges or even SVN:Externals. This thread is the outgrowth of the following SO thread, and if something was missed there, please DO post it there. This thread is trying to get
an understanding of how to Vendor branches, and the longer, clearer, and more dummied an explanation I receive the happier I will be.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

三生池水覆流年 2024-07-24 14:35:40

我认为子模块是“供应商分支”的最佳选择。
这是你应该如何使用 submod...嗯,开玩笑。

只是一个想法; 您想要:

  • 在同一目录中开发主项目和子项目(这称为“系统方法”:您开发、标记和合并所有系统)
  • 或查看您的子项目作为“供应商分支”(这是一个允许您访问供应商外部组件的明确定义版本 - 或“文件集” - 的分支,并且仅在该外部组件的每个版本中使用新版本进行更新:这称为“组件方法”,所有系统都被视为自己开发的单独组件的集合)

这两种方法不兼容:

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

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

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


萨姆古迪补充道:

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

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

这一切都是为了粒度问题:

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

萨姆古迪补充道:

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

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

最重要的是:克隆您的 my-awesome-framework 分支的人可以毫无问题地拉取您的 my-fantastic-plugin 子模块,因为您已经注册了子模块的公共克隆 URL。 命令

$ gh submodule init
$ gh submodule update

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

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

萨姆古迪提到:

我需要避免子树和子模块(参见问题),并且如果该方法合理,我宁愿解决这种需求,而无需过多争论

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

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

然而,我没有看到一种不使用子树合并或子模块来完成您想要的操作的本机 Git 方法。
我希望真正的 Git 大师能在这里发布更充分的答案。

I think submodules are the way to go when it comes to "vendor branch".
Here is how you should use submod... hmmm, just kidding.

Just a thought; you want:

  • to develop both main project and sub-project within the same directory (which is called a "system approach": you develop, tag and merge the all system)
  • or to view your sub-project as a "vendor branch" (which is a branch which allows you to access a well-defined version of a vendor external component - or "set of files" - , and which is only updated with the new version every release of that external component: that is called a "component-approach", the all system is viewed as a collection of separate components developed on their own)

The two approaches are not compatible:

  • The first strategy is compatible with a subtree-merge: you are working both on project and sub-project.
  • The second one is used with submodules, but submodules is used to define a configuration (list of tag you need to work): each git submodules, unlike svn:externals, are pinned to a particular commit id, and that is what allows you to define a configuration (as in SCM: "software configuration management")

I like the second approach because most of the time, when you have a project and a sub-project, their lifecycle is different (they are not developed at the same rhythm, not tagged together at the same time, nor with the same name).

What really prevents that approach ("component-based") in your question is the "both can be developed and updated from the same working directory" part.
I would really urge you to reconsider that requirement, as most IDE are perfectly capable to deals with multiple "sources" directories, and the sub-project development can be done in its own dedicated environment.


samgoody adds:

Imagine an eMap plugin for both Joomla and ModX. Both the plugin and the Joomla-specific code (which is part of Joomla, not of eMap) are developed while the plugin is inside Joomla. All paths are relative, the structure is rigid, and they must be distributed together - even though each project has its own lifecycle.

If I understand correctly, you are in a configuration where the development environment (the set of files you are working on) is quite the same than the distribution environment (the same set of file is copied on the release platform)

It all comes done to a granularity issue:

  • if both sets of files cannot exist one without the other, then they should be viewed as one big project (and subtree-merged), but that force them to be tagged and merged as one.
    -if one depends on the other (which can be developed alone), then they should be in their own Git repository and project, the first one depending on a specific commit of the second as a sub-module: if the sub-module is defined in the right subtree of the first component, all relative paths are respected.

samgoody adds:

The original thread listed issues with submodules - primarily that GitHub's download doesn't include them (vital to me) and that they get stuck on a particular commit.

I am not sure GitHub's download is an issue recently: that "Guides: Developing with Submodules" article does mention:

Best of all: people cloning your my-awesome-framework fork will have no problem pulling down your my-fantastic-plugin submodule, as you’ve registered the public clone URL for the submodule. The commands

$ gh submodule init
$ gh submodule update

Will pull the submodules into the current repository.

As for the "they get stuck on a particular commit": that is the all point of a submodule, allowing you to work with a configuration (list of tagged version of components) instead of a latest potentially unstable set of files.

samgoody mentions:

I need to avoid both subtrees and submodules (see question), and would rather address this need without arguing too much if the approach is justified

Your requirement is a perfectly legitimate one, and I do not want to judge its justification: my previous answers are only here to provide a larger context and try to illustrate the options usually available with a generic SCM tool.

Subtree merge should be the answer here, but would imply to merge back only commits made for files for the main project, and not commits made for the sub-projects. If you can manage that kind of partial merge, I would reckon it is the right path to follow.

I do not see however a native Git way to do what you want that does not use subtree-merge or submodule.
I hope a true Git guru will post here a more adequate answer.

晨与橙与城 2024-07-24 14:35:40

在我返回山区之前,我终于可以上网几个小时了。 我们会看看我是否有什么可以帮助澄清您的情况。

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

  1. 像 VonC(他通常会非常彻底地思考事情)一样,我认为 Git 不能完美满足您的要求。 和他一样,我认为使用子树合并模式是最合适的。 我不是 Git 专家,但我已经成功地将 Git 应用于广泛的需求。 也许 Git 不能满足您的需求:

    • SVN 将允许您在一个存储库中拥有多个存储库,这对您来说似乎很重要。 我认为这意味着使用外部或供应商分支模式来接近您想要的。

    • Mercurial 有一个扩展,Forest, 用于
      使用嵌套存储库,这似乎更适合您的思维模型。 15 个月前,我选择了 Git,而不是 Mercurial,但 HG 很稳定,而且在许多用途上,我认为它与 Git 相当。 我不知道该扩展程序的稳定性如何。

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

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

  3. 如果您的团队确实积极参与插件开发,或者您确实希望将项目和插件的开发历史集成到一个 Git 存储库中,那么只需使用一个 Git 存储库即可。 您可以提取插件及其历史记录作为供应商的记录 在这里解释,不时地。 这可能会给您带来比您预期更少的封装,但 Git 并不是为封装而设计的——Git 的数据结构基于跟踪整个项目内的更改。

也许我误解了你的情况,这些都不适用。 如果是这样我道歉。 感谢您和 VonC 提供的详细信息,这些详细信息填补了我最初在尝试理解您的问题时遇到的许多漏洞。

I finally have a few hours access to the net before I head back to the mountains. We'll see if I have anything to contribute clarity into your situation.

My (probably oversimplified) understanding is you have (offsite) vendor(s) developing plug-in(s) for your project where your (in-house) team is developing code for your main project using an externally sourced framework. Vendor doesn't make changes to your code and probably doesn't need your bleeding edge development, but does need your stable code to develop and test their work. Your team doesn't make changes to the framework, but does sometimes contribute changes to the plug-in.

  1. Like VonC (who usually thinks things thru very thoroughly) I don't think Git has a perfect fit for your requirements. And like him, I think using subtree merge pattern is the closest fit. I'm not a Git guru, but I have been successful at bending Git to a wide range of needs. Maybe Git doesn't meet your needs:

    • SVN will let you have multiple repos within one, which seems important for you. I think this would mean either using externals or the Vendor Branch pattern to come close to what you want.

    • Mercurial has an extension, Forest, for
      using nested repos, which seems to fit your mental model better. I chose Git over Mercurial 15 months ago, but HG was stable and for many uses I think it is comparable to Git. I don't know how stable the extension is.

  2. If I were in your situation, I'd use two Git repos -- one for the Plugin and one for the MainProject. The vendor would do development in the Plugin repo and would have a release branch that they pull current versions of the plug-in into without the rest of the development environment. That branch would be pulled into the MainProject repo as a vendor branch, and then merged into your main development branch. When your team works on a change to the plug-in, they develop it in a feature branch off of your main development branch and submit it to the vendor repo as patches. This gives you a very clean workflow, relatively easy to set-up and learn, while keeping the develop history segregated.

    I'm not trying to be argumentative, but simply to say this is Git's best fit for my understanding of your situation. The easiest way to set this up would use the subtree merge, but this does not run changes thru it in both directions, which was my objection to using that pattern.

  3. If your team is really actively involved in the plugin development or you really want to have the development history of both project and plug-in integrated in one Git repo, then just use one Git repo. You can extract the plug-in and its history for the records of your vendor as explained here, from time to time. This may give you less encapsulation than you intend, but Git is not designed for encapsulation -- Git's data structure is based on tracking changes within one whole project.

Maybe I've misunderstood your situation and none of this applies. If so I apologize. Thanks for the details that you and VonC have worked out, which have filled in many holes that I originally had in trying to understand your question.

地狱即天堂 2024-07-24 14:35:40

如果您只查找原始问题的标题:

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

https://www .roe.ch/Git_Reference

部分供应商分支模式

If you look just for the original question's title:

a good template for vendor branch pattern with git is on

https://www.roe.ch/Git_Reference

section Vendor branch pattern

戏剧牡丹亭 2024-07-24 14:35:40

无法使用子树合并,因为子项目正在积极进行中
开发,子树合并使得合并这些更新非常困难
回到原来的项目。

最初的问题(2009 年 4 月 20 日起)早于 git 的公告
子树
仅 10 天。 很难说
正是OP正在寻找的东西,但 git subtree 可能是正确的答案。

请注意,git subtree 是一个命令行工具。 如今它包含在
git。 它使用子树合并,但它不是同一回事。 它有一个 git subtree push 命令,旨在将本地更改合并回
上游子项目。

我被告知该解决方案在 SVN 世界中被称为“Vendor
分支”,并且它在 Git 中完成得非常简单,甚至不需要
寻址。 网络上有大量半生不熟的教程。

我写了 https://david.rothlis.net/vendor-branch/ 来解释供应商分支机构
git 中的内容,以及它们与 git 子树的关系。

Subtree-merging cannot be used, as the subproject is being actively
developed, and subtree merging makes it very difficult to merge those updates
back into the original project.

The original question (from Apr 20, 2009) predates the announcement of git
subtree
by only 10 days. It's hard to tell
exactly what the OP was looking for but git subtree could be the right answer.

Note that git subtree is a command-line tool. Nowadays it comes included with
git. It uses subtree merging but it isn't the same thing. It has a git subtree push command that's designed for merging your local changes back into
the upstream subproject.

I have been informed that the solution is known in the SVN world as "Vendor
Branches", and that it is so simply done in Git so as to not even need
addressing. Half-baked tutorials abound on the 'net.

I wrote https://david.rothlis.net/vendor-branch/ to explain vendor branches
in git, and how they relate to git subtree.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文