如何在递归初始化子模块时切换到另一个分支

Krz*_*iak 1 git git-checkout git-submodules

我有一个包含几个子模块的 git 存储库(请参阅示例)。它的结构如下所示:

I--A--B <- main
       \
        C <- branch-c
Run Code Online (Sandbox Code Playgroud)
  • 提交 A 添加了一个submodule-a
  • 提交 B 添加了一个submodule-b
  • 提交 C 添加一个submodule-con 分支branch-c

git clone --recurse-submodules <URL>当我仅使用submodule-a和子模块克隆上述存储库时, 子submodule-b模块将被初始化并克隆。

branch-c当我想使用来检查分支时git checkout branch-c,会创建 的目录submodule-c,但子模块本身并未初始化。命令输出中没有指示需要执行一些额外步骤。既不git status给出git diff任何提示。

相反,当我想branch-c使用它进行检查时git checkout --recurse-submodules branch-c,出现错误:

fatal: not a git repository: ../../.git/modules/subrepos/subrepo-c
fatal: could not reset submodule index
Run Code Online (Sandbox Code Playgroud)

如何branch-c在自动初始化所​​有子模块的同时签出(或切换到)分支?

phi*_*ilb 8

您的示例存储库缺少branch-c,因此它不是完整的 MCVE,但这是一个好的开始:)

git clone --recurse-submodules <URL>当我仅使用submodule-a和子模块克隆上述存储库时,子submodule-b模块将被初始化并克隆。

是的,这就是 的当前行为git clone --recurse-submodulesgit submodule update --init --recursive的签出阶段git clone使用 的调用来克隆和初始化子模块,因此,只有默认分支(或使用 指定的分支git clone -b <branch>)中记录的子模块才会被克隆和初始化。

branch-c当我想使用来检查分支时git checkout branch-c,会创建 的目录submodule-c,但子模块本身并未初始化。命令输出中没有指示需要执行一些额外步骤。既不git status给出git diff任何提示。

是的,不幸的是这仍然是 Git 的默认行为。默认情况下,子模块工作树不会被签出git checkout <branch>git submodule status(或只是git submodule)将显示带有-前缀的未初始化子模块。

相反,当我想branch-c使用它进行检查时git checkout --recurse-submodules branch-c,出现错误:

fatal: not a git repository: ../../.git/modules/subrepos/subrepo-c
fatal: could not reset submodule index
Run Code Online (Sandbox Code Playgroud)

这是一个很好的反射,但不幸的是它在特定情况下不起作用并导致这种糟糕的用户体验。git checkout --recurse-submodules <branch>假设记录的每个子模块branch-c都已经初始化。由于这里不是这种情况,因此它会出错,因为它找不到.git子模块的目录。信息可能会更清楚。您要做的(branch-c克隆存储库后第一次切换到)是非branch-c递归地签出,然后初始化子模块:

fatal: not a git repository: ../../.git/modules/subrepos/subrepo-c
fatal: could not reset submodule index
Run Code Online (Sandbox Code Playgroud)

然后,您将能够使用以下命令在分支之间正确切换--recurse-submodules

git checkout branch-c
git submodule update --init --recursive
Run Code Online (Sandbox Code Playgroud)

请注意,您可以在配置中进行设置以避免一直submodule.recurse使用。--recurse-submodules