Come "git clonare" compresi i sottomoduli?


1996

Sto cercando di inserire un sottomodulo in un repository. Il problema è che quando clono il repository principale, la cartella del sottomodulo è completamente vuota.

C'è un modo per farlo in modo che git clone parent_repoinserisca effettivamente i dati nella cartella del sottomodulo?

Ad esempio, http://github.com/cwolves/sequelize/tree/master/lib/ , nodejs-mysql-nativeindica un sottomodulo git esterno, ma quando eseguo il checkout del sequelizeprogetto, quella cartella è vuota.


4
Quel comando sarebbe git clone --recurse-submodules --remote-submodules(Q3 2019 Git 2.23): clonerà e aggiornerà i sottomoduli in un solo comando. Vedi la mia risposta modificata di seguito .
VonC,

Risposte:


2976

Con la versione 2.13 di Git e successive, è --recurse-submodulespossibile utilizzare invece di --recursive:

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

Nota dell'editore: -j8è un'ottimizzazione delle prestazioni opzionale che è diventata disponibile nella versione 2.8 e recupera fino a 8 sottomoduli alla volta in parallelo - vedi man git-clone.

Con la versione 1.9 di Git fino alla versione 2.12 ( -jflag disponibile solo nella versione 2.8+):

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

Con la versione 1.6.5 di Git e successive, puoi usare:

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

Per repository già clonati o versioni precedenti di Git, utilizzare:

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

124
Esiste un modo per specificare questo comportamento come predefinito nel repository git, in modo che i clonatori meno informati ottengano automaticamente un sottomodulo inizializzato?
NHDaly,

11
@NHDaly Purtroppo no. (Non che io sappia, almeno.)
Mathias Bynens,

6
E logicamente pensando al clone di git: ricorsivo popolerà anche tutti i sottomoduli di un sottomodulo, giusto?
jayarjo,


5
@toszter: è così saggio? Cosa succede se il repository in azienda necessita di una versione di un sottomodulo che non lo è master?
Gauthier,

498

Devi fare due cose prima che un sottomodulo venga riempito:

git submodule init 
git submodule update

8
Avevo paura di questo ... non ha alcun senso dal momento che stai verificando un progetto parziale in quel caso. Comprendo che gli aggiornamenti del sottomodulo non sono automatici, ma perché la versione associata non viene estratta automaticamente ?? C'è un modo per forzarlo? Ho un progetto con 3 livelli di sottomoduli e sembra assurdo dover attraversare così tanto solo per fare un checkout.
Segna il

11
Si prega di leggere la git-submodule(1)pagina man ( kernel.org/pub/software/scm/git/docs/git-submodule.html ). Scoprirai che git submodule updatesupporta un bel parametro chiamato --recursive.
joschi,

95
Perché non eseguirli entrambi in un solo comando? git submodule update --init(Vedi anche la mia risposta ).
Mathias Bynens,

9
Penso che sia meglio rispondere alla domanda con questi due comandi. Spiega meglio come eseguire l'attività.
schmijos,

6
@MathiasBynens Una macchina a cui ho appena effettuato l'accesso ha solo git 1.5.5.6, che apparentemente non supporta le istruzioni abbreviate, ma le supporta come due comandi.
Jack Poulson,

225

Git 2.23 (Q3 2019): se vuoi clonare e aggiornare i sottomoduli alla loro ultima revisione:

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

Se vuoi solo clonarli nel loro SHA1 registrato:

git clone --recurse-submodules

Vedi sotto.


Risposta originale 2010

Come menziona joschi nei commenti, git submoduleora supporta l' --recursiveopzione (Git1.6.5 e altro).

Se --recursivespecificato, questo comando ricercherà nei sottomoduli registrati e aggiornerà tutti i sottomoduli annidati all'interno.

Vedi Lavorare con i sottomoduli git in modo ricorsivo per la parte init.
Vedi git submodulespiegato di più.

Con la versione 1.6.5 di git e successive, puoi farlo automaticamente clonando il super-progetto con l' –-recursiveopzione:

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

Aggiornamento 2016, con git 2.8: vedi " Come velocizzare / parallelizzare i download dei sottomoduli git usando git clone --recursive? "

È possibile avviare il recupero del sottomodulo utilizzando più thread, in parallelo.
Per esempio:

git fetch --recurse-submodules -j2

Ancora meglio, con Git 2.23 (3 ° trimestre 2019), puoi clonare ed effettuare il checkout del sottomodulo nel loro ramo di tracciamento in un solo comando!

Vedi commit 4c69101 (19 maggio 2019) di Ben Avison ( bavison) .
(Unito da Junio ​​C Hamano - gitster- in commit 9476094 , 17 giugno 2019)

clone: aggiungi --remote-submodulesflag

Quando si utilizzava, in git clone --recurse-submodulesprecedenza non esisteva alcun modo per passare un --remotepassaggio al git submodule updatecomando implicito per qualsiasi caso d'uso in cui si desidera eseguire il checkout dei sottomoduli sul ramo di tracciamento remoto anziché con SHA-1 registrato nel superprogetto.

Questa patch corregge questa situazione.
In realtà passa --no-fetchper git submodule updatecosì per i motivi che sottomodulo è appena stato clonato, così recupero dal telecomando nuovamente serve solo a rallentare le cose.

Questo significa:

--[no-]remote-submodules:

Tutti i sottomoduli che vengono clonati useranno lo stato del ramo di tracciamento remoto del sottomodulo per aggiornare il sottomodulo, piuttosto che lo SHA-1 registrato del superprogetto. Equivale a passare --remotea git submodule update.


3
Quindi Git ha impiegato 14 anni per iniziare ad aggiungere il supporto adeguato per i sottomoduli, eh. Grazie per l'aggiornamento! E se avessi già un clone del repository principale senza sottomoduli e senza SHA1 registrato e desidero inserire l'ultima versione di ciascun sottomodulo. È fattibile?
Violet Giraffe

1
@VioletGiraffe Se quel repository clonato ha sottomoduli, ha "registrato SHA1". E git submodule update --init --recursive --remotebisognerebbe aggiornarli all'ultimo commit delle rispettive filiali. (es: stackoverflow.com/a/56981834/6309 )
VonC

1
Vorrei chiarire con un esempio: ho un progetto di modello su Github che utilizza sottomoduli e ho persino eseguito delle revisioni specifiche dei sottomoduli in questo repository di modelli. Ma quando creo un nuovo progetto da questa repo, nessuno dei comandi elencati (né clone --recurse-submodules --remote-submodulessubmodule update --init --recursive --remote) mi permetta effettivamente recuperare i subrepos. Tutto quello che ottengo è un file .gitmodules e non sono riuscito a trovare alcun modo per avviare i sottoreposi se non clonarli manualmente uno per uno. Vorrei almeno avere una sceneggiatura per farlo con submodule foreach...
Violet Giraffe,

Se conosci una soluzione, farei una domanda separata a cui potresti rispondere. Ecco il repository di prova che non riesco a trovare altro modo per iniziare se non a mano: github.com/VioletGiraffe/TEST
Violet Giraffe

@VioletGiraffe Questo perché si è aggiunto e commesso i .gitmodules ma non la gitlink ( stackoverflow.com/a/16581096/6309 , voci speciali nell'indice: stackoverflow.com/a/19354410/6309 ) Ecco un repository che fa avere il gitlink corretto registrato: github.com/tiagomazzutti/antlr4dart
VonC

110

[Risposta rapida]

È possibile utilizzare questo comando per clonare il repository con tutti i sottomoduli:

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

Oppure se hai già clonato il progetto, puoi utilizzare:

git submodule init
git submodule update

33

Se il tuo sottomodulo è stato aggiunto in un ramo assicurati di includerlo nel comando clone ...

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

Era più simile a quello che stavo cercando ... ma i sottomoduli elencano il loro ramo come "distaccato". :(
AceFunk,

28

Prova questo:

git clone --recurse-submodules

Inserisce automaticamente i dati del sottomodulo supponendo che abbiate già aggiunto i sottomoduli al progetto principale.


37
Si noti che --recurse-submodulese --recursivesono alias equivalenti .
Joel Purra,

@SuperUberDuper in quel caso puoi fare git submodule update --init --recursivecome spiegato in questa risposta
Enrico

25

Penso che tu possa andare con 3 passaggi:

git clone
git submodule init
git submodule update

21

risposta in ritardo

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

Dato che ho trascorso un'ora intera a giocherellare con un amico: anche se hai i diritti di amministratore su BitBucket, clona sempre il repository ORIGINAL e usa la password di chi possiede il repository. Fastidioso scoprire che ti sei imbattuto in questa minetrap: P.


È esattamente quello con cui ho a che fare. Quindi, stai dicendo che chiunque abbia bisogno di svilupparsi su un repository bitbucket con sottomoduli deve usare le credenziali del creatore del repository? Blech.
jsleuth,

@jsleuth Sembra così - fa schifo GRANDE TEMPO ... e lo so.
Kaiser

Sembra un bug. L'hai segnalato a Bitbucket?
Mathias Bynens,

@MathiasBynens Ti sei imbattuto in questo problema? Sono passati un anno e mezzo e in realtà non so se sia ancora così.
Kaiser,

4
Non risponde in modo descrittivo alla domanda di OP, ma descrive in dettaglio un bug non correlato in Bitbucket; che, per inciso, potrebbe essere semplicemente abbreviato per "utilizzare l'autenticazione con chiave SSH".
Treffynnon,

18

Prova questo per includere i sottomoduli nel repository git.

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

o

git clone --recurse-submodules

18

È possibile utilizzare la --recursivebandiera durante la clonazione di un repository. Questo parametro forza git a clonare tutti i sottomoduli definiti nel repository.

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

Dopo la clonazione, a volte i rami dei sottomoduli possono essere modificati, quindi eseguire questo comando dopo di esso:

git submodule foreach "git checkout master"

17

[Risposta rapida]

Dopo aver clonato il repository principale (che conteneva alcuni repository di sottomodulo), procedere come segue:

git submodule update --init --recursive

11

Il recupero parallelo di sottomoduli mira a ridurre il tempo necessario per recuperare un repository e tutti i relativi sottomoduli consentendo il recupero di più repository contemporaneamente. Questo può essere realizzato usando la nuova opzione --jobs, ad es .:

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

Secondo il team Git, questo può velocizzare notevolmente l'aggiornamento dei repository che contengono molti sottomoduli. Quando si utilizza --recurse-submodules senza la nuova opzione --jobs, Git recupererà i sottomoduli uno alla volta.

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


8

Ho avuto lo stesso problema per un repository GitHub. Nel mio account mancava la chiave SSH. Il processo è

  1. Genera chiave SSH
  2. Aggiunta di una nuova chiave SSH al tuo account GitHub

Quindi, è possibile clonare il repository con submodules ( git clone --recursive YOUR-GIT-REPO-URL)

o

Esegui git submodule inite git submodule updaterecupera i sottomoduli nel repository già clonato.


Sì, questo è un Permission denied (publickey). fatal: Could not read from remote repository.errore
Ender,

5

Prova questo.

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

Se il sottomodulo è stato aggiunto in un ramo, assicurarsi di aggiungerlo al comando clone.


5

Se si tratta di un nuovo progetto, puoi semplicemente fare così:

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

Se è già installato di:

$ cd YourProjectName (for the cases you are not at right directory) 
$ git submodule init
$ git submodule update
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.