子模块内部的Git子模块(嵌套子模块)


137

git子模块是否可以由其他几个git子模块组成,而super git repo可以获取每个子模块的内容?

我试图使用创建包含几个子模块的git repo的显而易见/天真的方法来做到这一点。

然后将此git repo添加到另一个git repo作为子模块。

然后试图通过从超级混帐回购协议的根目录拉git submodule init,然后git submodule update。但这无法获取子子模块。


我建议您使用TortoiseGit-在您的根目录中使用它,然后要求它使用Initialize,Recursive,Force checked更新所有子模块!
serup

Answers:


211

正如回顾性提到的那样-在git repo中添加--recursive

git submodule update --init --recursive

应该管用。


13
这对我有用。请注意,我错误地认为这git submodule init; git submodule update --recursive与上述同义,但事实并非如此。
jsdalton 2012年

+1我比使用的要好得多:git子模块foreach git子模块init ...然后git子模块更新--recursive
Joseph DeCarlo 2012年

不幸的是,这对我没有用。没有错误,没有消息,什么都没有。
路易·德·索萨

但是,如何更新这些完全嵌套的回购协议?当我传递--init标志时,我的一个子模块中的子模块只是被初始化为旧版本,而不是最新版本。
yoaquim

我可以git submodule foreach git pull origin master,它可以部分工作:子模块已更新,但有时HEAD会分离,并且对于子模块中的子模块,我无法提交直接子模块的更改,因为它具有“已修改的内容”而不是“新提交”(因为其自身的子模块具有“新提交”并进行了更新)。
yoaquim

55

正如Sridhar在下面的评论中(来自Git1.6.5 +),git clone --recursive现在是官方替代方法,其描述如下:

inamiy正确指出了Johan Herland(git submodule update --init --recursivecommit b13fd5c和git1.6.5中引入的命令。jherland

IceFire增加的评论

如果您只想检出一个子模块中的一个子模块,那么
git submodule update --init <submoduleName>该方法是可行的。


(旧的原始答案)

根据手册页

 git submodule update --recursive

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

根据您的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,2011年

@Sridhar:用于克隆,如Git1.6.5及更高版本中stackoverflow.com/questions/3796927/git-clone-submodulestackoverflow.com/questions/4251940/…中所述。我已经编辑了答案以反映这一点。
VonC

注意:如果您只想检出一个子模块中的一个子模块,那么git submodule update --init <submoduleName>该方法才行。我在寻找此答案时到达这里
IceFire

1
@IceFire谢谢。我已将您的评论包含在答案中,以提高知名度。
VonC
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.