Como "clonar git" incluindo submódulos?


1994

Estou tentando colocar um submódulo em um repositório. O problema é que, quando clono o repositório pai, a pasta do submódulo fica totalmente vazia.

Existe alguma maneira de fazê-lo para que git clone parent_reporealmente coloque dados na pasta do submódulo?

Por exemplo, http://github.com/cwolves/sequelize/tree/master/lib/ , nodejs-mysql-nativeestá apontando para um submódulo git externo, mas quando eu faço o checkout do sequelizeprojeto, essa pasta está vazia.


4
Esse comando seria git clone --recurse-submodules --remote-submodules(Q3 2019 Git 2.23): clonará e atualizará os submódulos em um comando. Veja minha resposta editada abaixo .
VonC 22/07/19

Respostas:


2976

Com a versão 2.13 do Git e posterior, --recurse-submodulespode ser usado em vez de --recursive:

git clone --recurse-submodules -j8 git://github.com/foo/bar.git
cd bar

Nota do editor: -j8é uma otimização de desempenho opcional que se tornou disponível na versão 2.8 e busca até 8 submódulos por vez em paralelo - consulte man git-clone.

Com a versão 1.9 do Git até a versão 2.12 ( -jsinalizador disponível apenas na versão 2.8+):

git clone --recursive -j8 git://github.com/foo/bar.git
cd bar

Com a versão 1.6.5 do Git e posterior, você pode usar:

git clone --recursive git://github.com/foo/bar.git
cd bar

Para repositórios já clonados ou versões mais antigas do Git, use:

git clone git://github.com/foo/bar.git
cd bar
git submodule update --init --recursive

123
Existe alguma maneira de especificar esse comportamento como padrão no seu repositório git, para que os clones menos informados obtenham automaticamente um sub-módulo inicializado?
NHDaly

11
@NHDaly Infelizmente, não. (Não que eu saiba, pelo menos.)
Mathias Bynens

6
E pensar logicamente que o git clone --recursive também preencherá todos os submódulos de um submódulo, certo?
Jayarjo #


5
@toszter: é tão sábio? E se o repositório de retenção precisar de uma versão de um submódulo que não seja master?
Gauthier

498

Você precisa fazer duas coisas antes que um submódulo seja preenchido:

git submodule init 
git submodule update

8
Eu tinha medo disso ... não faz sentido, pois você está verificando um projeto parcial nesse caso. Entendo que as atualizações do submódulo não são automáticas, mas por que a versão encadernada não é retirada automaticamente? Existe alguma maneira de forçá-lo? Eu tenho um projeto com três níveis de submódulos e parece absurdo ter que ir tão longe apenas para fazer um checkout.
Mark

11
Por favor, leia a git-submodule(1)página do manual ( kernel.org/pub/software/scm/git/docs/git-submodule.html ). Você descobrirá que git submodule updatesuporta um bom parâmetro chamado --recursive.
Joschi

95
Por que não apenas os dois em um comando? git submodule update --init(Veja também minha resposta ).
Mathias Bynens

9
Eu acho que é melhor responder à pergunta com esses dois comandos. Isso explica melhor como realizar a tarefa.
schmijos

6
@MathiasBynens Uma máquina na qual eu acabei de acessar apenas possui o git 1.5.5.6, que aparentemente não suporta a instrução abreviada, mas suporta dois comandos.
22413 Jack Poulson

223

Git 2.23 (terceiro trimestre de 2019): se você deseja clonar e atualizar os submódulos para a revisão mais recente:

git clone --recurse-submodules --remote-submodules

Se você apenas deseja cloná-los no SHA1 gravado:

git clone --recurse-submodules

Ver abaixo.


Resposta original 2010

Como joschi menciona nos comentários, git submoduleagora suporta a --recursiveopção (Git1.6.5 e mais).

Se --recursivefor especificado, esse comando recursará nos submódulos registrados e atualizará todos os submódulos aninhados.

Consulte Trabalhando com submódulos git recursivamente para a parte init.
Veja git submoduleexplicado para mais.

Com a versão 1.6.5 do git e posterior, você pode fazer isso automaticamente clonando o superprojeto com a –-recursiveopção:

git clone --recursive git://github.com/mysociety/whatdotheyknow.git

Atualização 2016, com git 2.8: consulte " Como acelerar / paralelizar downloads de submódulos git usando git clone --recursive? "

Você pode iniciar a busca do submódulo usando vários threads, em paralelo.
Para instâncias:

git fetch --recurse-submodules -j2

Melhor ainda, com o Git 2.23 (terceiro trimestre de 2019), você pode clonar e fazer check-out do submódulo para sua ramificação de rastreamento em um comando!

Veja commit 4c69101 (19 de maio de 2019) de Ben Avison ( bavison) .
(Incorporado por Junio ​​C Hamano - gitster- in commit 9476094 , 17 jun 2019)

clone: adicionar --remote-submodulessinalizador

Ao usar git clone --recurse-submodules, anteriormente, não havia maneira de passar uma --remoteopção para o git submodule updatecomando implícito para qualquer caso de uso em que você deseja que os submódulos sejam retirados em sua ramificação de rastreamento remoto, em vez de com o SHA-1 registrado no superprojeto.

Este patch corrige essa situação.
Na verdade, ele também passa --no-fetchcom git submodule updateo argumento de que o submódulo acabou de ser clonado, portanto, buscar no controle remoto novamente serve apenas para desacelerar as coisas.

Que significa:

--[no-]remote-submodules:

Todos os submódulos clonados usarão o status da ramificação de rastreamento remoto do submódulo para atualizar o submódulo, em vez do SHA-1 registrado do superprojeto. Equivalente a passar --remotepara git submodule update.


3
Então, o Git levou 14 anos para começar a adicionar suporte adequado aos submódulos, hein. Obrigado pela atualização! E se eu já tiver um clone do repositório principal sem submódulos e sem um SHA1 gravado, e desejar extrair a versão mais recente de cada submódulo. Isso é factível?
Giraffe Violet

1
@VioletGiraffe Se esse repositório clonado tiver submódulos, ele "gravou SHA1". E a git submodule update --init --recursive --remotedeve atualizá-los para o commit mais recente de sua respectiva ramificação. (ex: stackoverflow.com/a/56981834/6309 )
VonC

1
Deixe-me esclarecer com um exemplo: eu tenho um projeto de modelo no Github que usa submódulos e até cometei revisões específicas dos submódulos neste repositório de modelos. Mas quando crio um novo projeto a partir deste repositório, nenhum dos comandos que você listou (nem clone --recurse-submodules --remote-submodulesnem submodule update --init --recursive --remote) me permitiu buscar os sub-repositórios. Tudo o que recebo é um arquivo .gitmodules, e não consegui encontrar nenhuma maneira de iniciar os subrepos além de cloná-los manualmente, um por um. Eu gostaria de ter pelo menos um script para fazê-lo com submodule foreach...
Violet Giraffe

Se você souber uma solução, eu faria uma pergunta separada que você poderia responder. Aqui está a repo teste que eu não posso encontrar alguma maneira para o init que não seja à mão: github.com/VioletGiraffe/TEST
Violet Giraffe

@VioletGiraffe Isso porque você adicionou e confirmou os .gitmodules, mas não o gitlink ( stackoverflow.com/a/16581096/6309 , entradas especiais no índice: stackoverflow.com/a/19354410/6309 ) Aqui está um repositório que faz tenha o gitlink adequado registrado: github.com/tiagomazzutti/antlr4dart
VonC

109

[Resposta rápida]

Você pode usar este comando para clonar seu repositório com todos os submódulos:

git clone --recursive YOUR-GIT-REPO-URL

Ou, se você já clonou o projeto, pode usar:

git submodule init
git submodule update

33

Se o seu submódulo foi adicionado a um ramo, inclua-o no comando clone ...

git clone -b <branch_name> --recursive <remote> <directory>

Era mais como o que eu estava procurando ... mas os submódulos listam sua ramificação como 'desanexada'. :(
AceFunk 25/07/19

28

Tente o seguinte:

git clone --recurse-submodules

Ele puxa automaticamente os dados do submódulo, assumindo que você já adicionou os submódulos ao projeto pai.


37
Observe que --recurse-submodulese --recursivesão aliases equivalentes .
Joel Purra

@SuperUberDuper, nesse caso, você pode fazer o git submodule update --init --recursiveque foi explicado nesta resposta
Enrico

25

Eu acho que você pode seguir 3 etapas:

git clone
git submodule init
git submodule update

21

Resposta atrasada

// git CLONE INCLUDE-SUBMODULES ADDRESS DESTINATION-DIRECTORY
git clone --recursive https://USERNAME@bitbucket.org/USERNAME/REPO.git DESTINATION_DIR

Como passei uma hora inteira brincando com um amigo: Mesmo se você tiver direitos de administrador no BitBucket, sempre clone o repositório ORIGINAL e use a senha de quem é o dono do repositório. É irritante descobrir que você encontrou esse minetrap: P


É exatamente com isso que estou lidando. Então, você está dizendo que qualquer pessoa que precise desenvolver um repositório de bitbucket que possua submódulos deve usar as credenciais do criador do repositório? Blech.
Jsleuth

@jsleuth Parece que sim - suga MUITO TEMPO ... e eu sei disso.
Kaiser #

Isso soa como um bug. Você denunciou ao Bitbucket?
Mathias Bynens

@MathiasBynens Você encontrou este problema? É um ano e meio depois e eu realmente não sei se esse ainda é o caso.
Kaiser #

4
Ele não responde de forma descritiva à pergunta dos OPs, mas detalha um bug não relacionado no Bitbucket; que, aliás, poderia ser reduzido para "usar autenticação de chave SSH".
Treffynnon

18

Tente isso para incluir submódulos no repositório git.

git clone -b <branch_name> --recursive <remote> <directory>

ou

git clone --recurse-submodules

18

Você pode usar o --recursivesinalizador ao clonar um repositório. Este parâmetro força o git a clonar todos os submódulos definidos no repositório.

git clone --recursive git@repo.org:your_repo.git

Após a clonagem, as ramificações do submódulo às vezes podem ser alteradas; portanto, execute este comando após:

git submodule foreach "git checkout master"

17

[Resposta rápida]

Após a clonagem do repositório pai (que continha algum repositório de submódulo), faça o seguinte:

git submodule update --init --recursive

11

A busca paralela de submódulos visa reduzir o tempo necessário para buscar um repositório e todos os seus submódulos relacionados, permitindo a busca de vários repositórios de uma só vez. Isso pode ser feito usando a nova opção --jobs, por exemplo:

git fetch --recurse-submodules --jobs=4

Segundo a equipe do Git, isso pode acelerar substancialmente a atualização de repositórios que contêm muitos submódulos. Ao usar --recurse-submodules sem a nova opção --jobs, o Git buscará os submodules um por um.

Fonte: http://www.infoq.com/news/2016/03/git28-released


8

Eu tive o mesmo problema para um repositório GitHub. Faltava à minha conta a chave SSH. O processo é

  1. Gerar chave SSH
  2. Adicionando uma nova chave SSH à sua conta do GitHub

Em seguida, você pode clonar o repositório com submodules ( git clone --recursive YOUR-GIT-REPO-URL)

ou

Execute git submodule inite git submodule updatebusque submódulos no repositório já clonado.


Sim, isso é Permission denied (publickey). fatal: Could not read from remote repository.erro
Ender

5

Tente isso.

git clone -b <branch_name> --recursive <remote> <directory>

Se você adicionou o submódulo em uma ramificação, certifique-se de adicioná-lo ao comando clone.


5

Se for um novo projeto, basta fazer o seguinte:

$ git clone --recurse-submodules https://github.com/chaconinc/YourProjectName 

Se já estiver instalado, então:

$ cd YourProjectName (for the cases you are not at right directory) 
$ git submodule init
$ git submodule update
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.