172

Is it possible for a git submodule to be made of several other git submodules, and the super git repo to fetch the contents for each submodule?

I have tried to do this using the obvious/naive approach of creating a git repo holding several submodules.

Then adding this git repo to another git repo as a submodule.

Then attempting to pull from the root directory of the super git repo by git submodule init and then git submodule update. But this fails to fetch the sub-submodules.

Philip Kirkbride
  • 21,381
  • 38
  • 125
  • 225
firstresponder
  • 5,000
  • 8
  • 32
  • 38
  • I suggest that you use TortoiseGit -- use it in your root and then ask it to update all submodules with Initialize, Recursive, Force checked ! – serup Nov 20 '18 at 13:53

2 Answers2

262

As mentioned in Retrospectively add --recursive to a git repo

git submodule update --init --recursive

should work.

Community
  • 1
  • 1
inamiy
  • 2,896
  • 2
  • 17
  • 13
  • 19
    This worked for me. Note that I erroneously thought that `git submodule init; git submodule update --recursive` was synonymous with the above, but it is not. – jsdalton Mar 21 '12 at 16:43
  • +1 I like this much better than what I was using: git submodule foreach git submodule init ... then git submodule update --recursive – Joseph DeCarlo Mar 27 '12 at 14:19
  • Unfortunately this didn't work for me. No erros, no messages, nothing. – Luís de Sousa Feb 10 '14 at 15:50
  • How do you update theses fully nested repos though? When I pass in the `--init` flag, the submodules, within one of my submodules, just get initialized to old versions, not the most current ones. – cintron May 12 '15 at 03:13
  • I do `git submodule foreach git pull origin master`, and it works partially: submodules are updated, but sometimes the `HEAD` gets detached and for submodules within submodules, I can't commit my direct submodule's changes because it has "modified content" not "new commits" (since its own submodules have "new commits" and are updated). – cintron May 12 '15 at 03:22
  • You can also add `--remote` to this command if you'd like to fetch from a specific branch: `git submodule update --init --recursive --remote` – felipekm Feb 15 '22 at 20:22
60

As Sridhar comments below, from Git1.6.5+, git clone --recursive is now the official alternative, described in:

inamiy correctly points out the git submodule update --init --recursive command, introduced in commit b13fd5c, again in git1.6.5, by Johan Herland (jherland).

And IceFire adds in the comments:

If you would like to checkout only one submodule of a submodule, then
git submodule update --init <submoduleName> is the way to go.


(older original answer)

According to the manual page

 git submodule update --recursive

should update any nested submodules. But the init part may not be recursive.

Depending on your version of Git, you could fall back to a more "scripting" approach, with this article Recursively Updating Git Submodules which allows for recursive init and update:

#!/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);
}
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 1
    Is not `git clone --recursive` sufficient? – Sridhar Ratnakumar Jan 12 '11 at 21:13
  • @Sridhar: it is, for cloning, as mentioned in http://stackoverflow.com/questions/3796927/git-clone-submodule and http://stackoverflow.com/questions/4251940/retrospectively-add-recursive-to-a-git-repo/4261001#4261001, from Git1.6.5 and later. I have edited my answer to reflect that. – VonC Jan 12 '11 at 21:19
  • 1
    Note: If you would like to checkout only one submodule of a submodule, then `git submodule update --init ` is the way to go; I got here when searching for this answer – IceFire Aug 30 '17 at 15:09
  • 1
    @IceFire Thank you. I have included your comment in the answer for more visibility. – VonC Aug 30 '17 at 15:12