嵌套子模块中的Git子模块(嵌套子模块)

175

一个 git 子模块能否由多个其他的 git 子模块组成?如果可以,那么超级 git 仓库是否可以获取每个子模块的内容呢?

我曾尝试通过创建一个包含多个子模块的 git 仓库,并将该 git 仓库作为子模块添加到另一个 git 仓库中来实现这一点。

然后,我尝试从超级 git 仓库的根目录中运行 git submodule initgit submodule update 命令进行拉取,但是这未能获取子子模块的内容。


我建议你使用TortoiseGit--在根目录中使用它,然后要求它使用Initialize、Recursive、Force选项来更新所有子模块! - serup
2个回答

265

19
这对我很有效。请注意,我错误地认为 git submodule init; git submodule update --recursive 与上述命令同义,但实际上并不是。 - jsdalton
+1 我更喜欢这个方法,比我之前用的好多了:git submodule foreach git submodule init ... 然后 git submodule update --recursive - Joseph DeCarlo
很遗憾,这对我没有起作用。没有错误,没有消息,什么都没有。 - Luís de Sousa
你怎么更新这些完全嵌套的仓库呢?当我传入 --init 标志时,子模块中的一个子模块中的版本只是被初始化为旧版本,而不是最新版本。 - cintron
我执行 git submodule foreach git pull origin master 命令,它部分地起作用:子模块得到更新,但有时候 HEAD 会被分离,对于嵌套的子模块,我无法提交直接子模块的更改,因为它具有“修改内容”而不是“新提交”(因为其自身的子模块具有“新提交”并已更新)。 - cintron
如果您想从特定分支获取,请在此命令中添加 --remotegit submodule update --init --recursive --remote - felipekm

60

正如Sridhar在下面评论中所说,从Git1.6.5+开始,git clone --recursive现在是官方的替代方法,描述如下:

inamiy 正确地指出git submodule update --init --recursive命令,该命令在提交 b13fd5c中首次引入,再次在git1.6.5中由Johan Herland (jherland)引入。

IceFire 在评论中添加了以下内容

如果您只想检出子模块的一个子模块,则使用
git submodule update --init <submoduleName>即可。


根据手册页面
 git submodule update --recursive

应该更新任何嵌套的子模块。但是初始化部分可能不是递归的。

根据您的Git版本,您可以回退到更多的“脚本”方法,使用此文章 递归更新Git子模块,允许递归初始化和更新:

#!/usr/bin/perl

use strict;
use Cwd;

init_and_update();

exit;

sub init_and_update
{
    my $start_path = cwd();

    my %paths;
    my $updated;

    do
    {
        my $data = `find . -name '.gitmodules'`;
        chomp($data);

        $data =~ s/\/\.gitmodules//g;

        foreach my $path (split(/\n/, $data))
        {
            $paths{$path} = '' if($paths{$path} eq '');
        }

        $updated = 0;

        foreach my $path (sort keys %paths)
        {
            if($paths{$path} eq '')
            {
                chdir($path);
                `git submodule init 2>&1`;
                `git submodule update 2>&1`;
                chdir($start_path);

                if($ARGV[0] eq '--remove-gitmodules')
                {
                    unlink("$path/.gitmodules");
                }

                $paths{$path} = 1;

                $updated++;
            }
        }
    } while($updated);
}

1
git clone --recursive 不够吗? - Sridhar Ratnakumar
@Sridhar:正如https://dev59.com/jm865IYBdhLWcg3wd-ce和https://dev59.com/pG855IYBdhLWcg3wm1i3#4261001中所提到的,从Git1.6.5开始,可以使用克隆功能。我已经编辑了我的答案以反映这一点。 - VonC
1
注意:如果您只想检出子模块中的一个子模块,则 git submodule update --init <submoduleName> 是正确的方法;我在搜索这个答案时找到了它。 - IceFire
1
@IceFire 谢谢你。我已将你的评论包含在答案中以增加可见性。 - VonC

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