Sub-módulo Git dentro de um submódulo (submódulos aninhados)

137

É possível que um submódulo git seja feito de vários outros submódulos git e o repositório super git busque o conteúdo de cada submódulo?

Eu tentei fazer isso usando a abordagem óbvia / ingênua de criar um repositório git contendo vários submódulos.

Em seguida, adicione esse repositório git a outro repositório git como um submódulo.

Em seguida, tente extrair do diretório raiz do repositório super git git submodule inite então git submodule update. Mas isso falha ao buscar os submódulos.

firstresponder
fonte
Eu sugiro que você use o TortoiseGit - use-o em sua raiz e peça para atualizar todos os submódulos com Inicializar, Recursivo, Forçar marcado!
Serup

Respostas:

211

Como mencionado em Retrospectivamente, adicione --recursive a um repositório git

git submodule update --init --recursive

Deveria trabalhar.

inamiy
fonte
13
Isso funcionou para mim. Note que pensei erroneamente que git submodule init; git submodule update --recursiveera sinônimo do que foi dito acima, mas não é.
jsdalton
+1 I como este muito melhor do que o que eu estava usando: git submódulo foreach git submódulo de inicialização ... então atualização submodule git --recursive
Joseph DeCarlo
Infelizmente isso não funcionou para mim. Sem erros, sem mensagens, nada.
Luís de Sousa
Como você atualiza esses repositórios totalmente aninhados? Quando passo a --initbandeira, os submódulos, dentro de um dos meus submódulos, são inicializados em versões antigas, não nas mais atuais.
Yoaquim
Sim git submodule foreach git pull origin master, e funciona parcialmente: os submódulos são atualizados, mas às vezes HEADsão desanexados e, para submódulos nos submódulos, não consigo confirmar as alterações do meu submódulo direto porque ele tem "conteúdo modificado" e não "novos commit" (pois seus próprios submódulos têm "novas confirmações" e são atualizadas).
Yoaquim
55

Como Sridhar comenta abaixo, do Git1.6.5 +, git clone --recursiveagora é a alternativa oficial, descrita em:

inamiy indica corretamente o git submodule update --init --recursivecomando, introduzido no commit b13fd5c , novamente no git1.6.5, de Johan Herland ( jherland) .

E o IceFire acrescenta nos comentários :

Se você gostaria de fazer check-out de apenas um submódulo de um submódulo, esse
git submodule update --init <submoduleName>é o caminho a seguir.


(resposta original mais antiga)

De acordo com a página do manual

 git submodule update --recursive

deve atualizar todos os submódulos aninhados. Mas a parte init pode não ser recursiva.

Dependendo da sua versão do Git, você pode recorrer a uma abordagem mais "scripting", com este artigo Atualizando recursivamente os submódulos do Git, que permite a inicialização e atualização recursivas:

#!/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
fonte
1
Não é git clone --recursivesuficiente?
Sridhar Ratnakumar
@Sridhar: é, para clonagem, como mencionado em stackoverflow.com/questions/3796927/git-clone-submodule e stackoverflow.com/questions/4251940/… , do Git1.6.5 e posterior. Eu editei minha resposta para refletir isso.
VonC 12/01
Nota: Se você gostaria de fazer check-out apenas de um submódulo de um submódulo, então git submodule update --init <submoduleName>é o caminho a seguir; Eu cheguei aqui ao procurar por esta resposta
IceFire
1
@IceFire Obrigado. Incluímos seu comentário na resposta para obter mais visibilidade.
VonC 30/08/19