在子模块中添加一个git子模块(嵌套子模块)

15

如此问题所述

一个 Git 子模块能够由多个其他 Git 子模块组成,而主 Git 仓库能够获取每个子模块的内容吗?

作者假定了这样的 Git 子模块层级结构:

  • repo1
    • submodule xyz1
    • submodule xyz2
  • repo2
    • submodule repo1

这个问题是关于在子模块中嵌套子模块的可能性:

  • repo1
    • submodule a
      • submodule ab
      • submodule ac

一个 .gitmodules 的真实示例应该长这样:

[submodule "Source/V8"]
    path = Source/V8
    url = https://chromium.googlesource.com/v8/v8.git
[submodule "Source/V8/build/gyp"]
    path = Source/V8/build/gyp
    url =  https://chromium.googlesource.com/external/gyp
[submodule "Source/V8/third_party/cygwin"]
    path = Source/V8/third_party/cygwin
    url = https://chromium.googlesource.com/chromium/deps/cygwin
[submodule "Source/V8/third_party/python_26"]
    path = Source/V8/third_party/python_26
    url = https://chromium.googlesource.com/chromium/deps/python_26
[submodule "Source/V8/third_party/icu"]
    path = Source/V8/third_party/icu
    url = https://chromium.googlesource.com/chromium/deps/icu52
[submodule "Source/V8/testing/gtest"]
    path = Source/V8/testing/gtest
    url = https://chromium.googlesource.com/chromium/testing/gtest
[submodule "Source/V8/testing/gmock"]
    path = Source/V8/testing/gmock
    url = https://chromium.googlesource.com/chromium/testing/gtest

请注意,子模块的路径是嵌套的:

  • Source/V8
    • Source/V8/build/gyp
    • Source/V8/third_party/cygwin

我尝试了以下示例但没有成功:

 git submodule add https://chromium.googlesource.com/v8/v8.git   
 Source/V8
 git submodule add https://chromium.googlesource.com/external/gyp 
 Source/V8/build/gyp 

导致结果:

 The following path is ignored by one of your .gitignore files:
 Source/V8/build/gyp
 Use -f if you really want to add it.

使用 git submodule add -f 会导致:

Cloning into 'Source/V8/build/gyp'...
remote: Sending approximately 10.28 MiB ...
remote: Total 16486 (delta 10444), reused 16486 (delta 10444)
Receiving objects: 100% (16486/16486), 10.28 MiB | 2.07 MiB/s, done.
Resolving deltas: 100% (10452/10452), done.
Checking connectivity... done.
fatal: Pathspec 'Source/V8/build/gyp' is in submodule 'Source/V8'
Failed to add submodule 'Source/V8/build/gyp'
请告诉我是否有可能实现这个案例。 更新:请注意,这个问题是关于创建子模块结构,而不是初始化它。

你解决了吗? - evk1206
3
这个使用案例没有解决方案。 - chrisber
4个回答

0

简短回答:是的。 在一天结束时,子模块就是一个模块,但位于另一个模块内部。

这意味着,如果您设置了一个带有子模块的父级存储库。您可以进入该子模块并在其中设置另一个模块。 这样,父级存储库将看到您在子模块中进行了一些更改,但不会看到您在其中又有另一个子模块。


0
根据我对Git v2.40.1源代码的分析,看起来你试图做的事情是不可能的。 builtin/submodule--helper.c包含产生“无法添加子模块'Source/V8/build/gyp'”错误的代码:
static void configure_added_submodule(struct add_data *add_data)
{
    // […]
    struct child_process add_submod = CHILD_PROCESS_INIT;
    // […]
    add_submod.git_cmd = 1;
    strvec_pushl(&add_submod.args, "add",
             "--no-warn-embedded-repo", NULL);
    // […]
    if (run_command(&add_submod))
        die(_("Failed to add submodule '%s'"), add_data->sm_path);
    // […]
}

换句话说,为了配置添加的子模块,Git 需要使用一些参数运行 git add。git add 的代码无条件调用 die_path_inside_submodule()(链接1),这是导致“fatal: Pathspec 'Source/V8/build/gyp' is in submodule 'Source/V8'”错误的函数(链接2)
Git 开发人员的意图很明确:仓库不应该将文件添加到其子模块中,而您的示例 .gitmodules 文件正在尝试将文件添加到仓库的子模块中。

话虽如此,你为什么想要这样的层级结构呢?

  • repo1
    • 子模块a
      • 子模块ab
      • 子模块ac

为什么不使用这种层级结构呢?

  • repo1
    • 子模块xyz1
    • 子模块xyz2
  • repo2
    • 子模块repo1

-1
子模块应该添加到一个仓库中,而不是一个子模块中。
然后,在顶层仓库中跟踪它们后,顶层仓库可以作为另一个项目的子模块使用,从而形成嵌套子模块结构。
在您的示例中,您应该将gyp作为子模块添加到V8项目中。如果您无法影响顶级项目,那么您应该问自己为什么要将子模块添加到该项目中?
当所需的结构建立时,您可以使用@iclman建议的命令将所有子模块带入:
git submodule update --init --recursive

欢迎来到 Stack Overflow,我们很感激您的贡献!您能否编辑您的问题并自我包含,解释一下 iclman 说了什么?请参阅 https://stackoverflow.com/help/how-to-answer。 - B--rian

-1

是的,嵌套子模块是可能的,尽管不一定建议这样做。 如果你真的想创建嵌套子模块,你必须使用以下命令:

git submodule update --init --recursive

其实之前已经有类似的问题被问过了,你可以看一下这里

3
抱歉,你的回答不正确,请仔细比较两个问题,我的问题是关于创建子模块结构,而不是初始化它。 - chrisber
1
@Karl2011,你尝试过执行 git submodule add https://chromium.googlesource.com/v8/v8.git Source/V8 吗?然后进入 Source/V8 目录。在该目录中,你应该执行 git submodule add https://chromium.googlesource.com/external/gyp external/gyp。这样,external/gyp 目录就成为了 Source/V8 中的一个子模块。 - iclman
2
是的,我尝试过了,但这会将子模块添加到v8存储库而不是根存储库。 - chrisber
1
Source/V8已经是根仓库的子模块。因此,您不能将Source/V8/external/gyp添加为根仓库的子模块。您只能将其作为Source/V8的子模块添加。另一个选项是在与Source/V8同级别的位置添加external/gyp,然后从Source/V8/external/gyp创建符号链接到External/gyp。在这种情况下,External/gyp将被创建为根存储库的子模块。 - iclman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接