Comment «git clone» y compris les sous-modules?

1996

J'essaie de mettre un sous-module dans un dépôt. Le problème est que lorsque je clone le référentiel parent, le dossier du sous-module est entièrement vide.

Existe-t-il un moyen de faire en sorte que les git clone parent_repodonnées soient effectivement placées dans le dossier du sous-module?

Par exemple, http://github.com/cwolves/sequelize/tree/master/lib/ , nodejs-mysql-nativepointe du doigt un sous - module git externe, mais quand j'extraira le sequelizeprojet, ce dossier est vide.

marque
la source
4
Cette commande serait git clone --recurse-submodules --remote-submodules(Q3 2019 Git 2.23): elle clonera et mettra à jour les sous-modules en une seule commande. Voir ma réponse modifiée ci-dessous .
VonC

Réponses:

2976

Avec la version 2.13 de Git et versions ultérieures, --recurse-submodulespeut être utilisé à la place de --recursive:

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

Note de l'éditeur: -j8est une optimisation des performances facultative qui est devenue disponible dans la version 2.8 et récupère jusqu'à 8 sous-modules à la fois en parallèle - voir man git-clone.

Avec la version 1.9 de Git jusqu'à la version 2.12 ( -jindicateur uniquement disponible dans la version 2.8+):

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

Avec la version 1.6.5 de Git et versions ultérieures, vous pouvez utiliser:

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

Pour les référentiels déjà clonés ou les anciennes versions de Git, utilisez:

git clone git://github.com/foo/bar.git
cd bar
git submodule update --init --recursive
Mathias Bynens
la source
124
Existe-t-il un moyen de spécifier ce comportement par défaut dans votre référentiel git, afin que les cloneurs moins informés obtiennent automatiquement un sous-module initialisé?
NHDaly
11
@NHDaly Malheureusement, non. (Pas que je sache, au moins.)
Mathias Bynens
6
Et penser logiquement git clone --recursive remplira également tous les sous-modules d'un sous-module, non?
jayarjo
3
@NHDaly il ne semble pas: stackoverflow.com/questions/4251940/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
5
@toszter: est-ce si sage? Que faire si la mise en pension a besoin d'une version d'un sous-module qui ne l' est pasmaster ?
Gauthier
498

Vous devez faire deux choses avant qu'un sous-module soit rempli:

git submodule init 
git submodule update
LiraNuna
la source
8
J'avais peur de ça ... ça n'a aucun sens puisque vous vérifiez un projet partiel dans ce cas. Je comprends que les mises à jour du sous-module ne sont pas automatiques, mais pourquoi la version liée n'est-elle pas automatiquement extraite ?? Y a-t-il un moyen de le forcer? J'ai un projet avec 3 niveaux de sous-modules et il semble absurde d'avoir à parcourir ce chemin juste pour faire un checkout.
Mark
11
Veuillez lire la git-submodule(1)page de manuel ( kernel.org/pub/software/scm/git/docs/git-submodule.html ). Vous découvrirez que git submodule updateprend en charge un joli paramètre appelé --recursive.
joschi
95
Pourquoi ne pas les faire tous les deux en une seule commande? git submodule update --init(Voir aussi ma réponse ).
Mathias Bynens
9
Je pense qu'il vaut mieux répondre à la question avec ces deux commandes. Cela explique mieux comment accomplir la tâche.
schmijos
6
@MathiasBynens Une machine à laquelle je viens de me connecter n'a que git 1.5.5.6, qui ne supporte apparemment pas l'instruction raccourcie, mais la prend en charge comme deux commandes.
Jack Poulson
225

Git 2.23 (Q3 2019): si vous souhaitez cloner et mettre à jour les sous-modules vers leur dernière révision:

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

Si vous voulez simplement les cloner sur leur SHA1 enregistré:

git clone --recurse-submodules

Voir ci-dessous.


Réponse originale 2010

Comme le mentionne joschi dans les commentaires, git submoduleprend désormais en charge l' --recursiveoption (Git1.6.5 et plus).

Si --recursiveest spécifié, cette commande récursive dans les sous-modules enregistrés et mettra à jour tous les sous-modules imbriqués à l'intérieur.

Voir Utilisation récursive des sous-modules git pour la partie init.
Voir git submoduleexpliqué pour plus.

Avec la version 1.6.5 de git et versions ultérieures, vous pouvez le faire automatiquement en clonant le super-projet avec l' –-recursiveoption:

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

Mise à jour 2016, avec git 2.8: voir " Comment accélérer / paralléliser les téléchargements de sous-modules git en utilisant git clone --recursive? "

Vous pouvez lancer la récupération du sous-module à l'aide de plusieurs threads, en parallèle.
Par exemple:

git fetch --recurse-submodules -j2

Encore mieux, avec Git 2.23 (Q3 2019), vous pouvez cloner et extraire le sous-module vers leur branche de suivi en une seule commande!

Voir commit 4c69101 (19 mai 2019) de Ben Avison ( bavison) .
(Fusionné par Junio ​​C Hamano - gitster- dans commit 9476094 , 17 juin 2019)

clone: ajouter un --remote-submodulesindicateur

Lors de l'utilisation, git clone --recurse-submodulesil était auparavant impossible de passer un --remotecommutateur à la git submodule updatecommande implicite pour tout cas d'utilisation où vous souhaitez que les sous-modules soient extraits sur leur branche de suivi à distance plutôt qu'avec le SHA-1 enregistré dans le superprojet.

Ce patch corrige cette situation.
Il passe en fait --no-fetchà git submodule updateaussi bien sur le terrain , ils le sous - module vient seulement d' être clonés, donc aller chercher la télécommande seulement sert à nouveau ralentir les choses.

Cela signifie:

--[no-]remote-submodules:

Tous les sous-modules qui sont clonés utiliseront l'état de la branche de suivi à distance du sous-module pour mettre à jour le sous-module, plutôt que le SHA-1 enregistré du superprojet. Équivalent à passer --remoteà git submodule update.

VonC
la source
3
Il a donc fallu 14 ans à Git pour commencer à ajouter un support approprié pour les sous-modules, hein. Merci pour la mise à jour! Et si j'ai déjà un clone du référentiel principal sans sous-modules et sans SHA1 enregistré, et que je veux récupérer la dernière version de chaque sous-module. Est-ce faisable?
Violet Giraffe
1
@VioletGiraffe Si ce référentiel cloné a des sous-modules, il a "enregistré SHA1". Et git submodule update --init --recursive --remotevous devez les mettre à jour avec la dernière validation de leur branche respective. (ex: stackoverflow.com/a/56981834/6309 )
VonC
1
Permettez-moi de clarifier avec un exemple: j'ai un projet de modèle sur Github qui utilise des sous-modules, et j'ai même commis des révisions spécifiques des sous-modules dans ce dépôt de modèle. Mais lorsque je crée un nouveau projet à partir de ce dépôt, aucune des commandes que vous avez répertoriées (ni clone --recurse-submodules --remote-submodulesni submodule update --init --recursive --remote) ne me permet réellement de récupérer les sous-dépôts. Tout ce que j'obtiens est un fichier .gitmodules, et je n'ai pas pu trouver d'autre moyen de lancer les sous-dépôts que de les cloner manuellement un par un. Je voudrais au moins avoir un script pour le faire avec submodule foreach...
Violet Giraffe
Si vous connaissez une solution, je poserais une question distincte à laquelle vous pourriez répondre. Voici le repo de test que je ne trouve aucun moyen d'initier autrement qu'à la main: github.com/VioletGiraffe/TEST
Violet Giraffe
@VioletGiraffe C'est parce que vous avez ajouté et validé les .gitmodules mais pas le gitlink ( stackoverflow.com/a/16581096/6309 , entrées spéciales dans l'index: stackoverflow.com/a/19354410/6309 ) Voici un référentiel qui ne enregistrez le gitlink approprié: github.com/tiagomazzutti/antlr4dart
VonC
110

[Réponse rapide]

Vous pouvez utiliser cette commande pour cloner votre référentiel avec tous les sous-modules:

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

Ou si vous avez déjà cloné le projet, vous pouvez utiliser:

git submodule init
git submodule update
Javier C.
la source
33

Si votre sous-module a été ajouté dans une branche, assurez-vous de l'inclure dans votre commande de clonage ...

git clone -b <branch_name> --recursive <remote> <directory>
Mars Redwyne
la source
Cela ressemblait plus à ce que je cherchais ... mais les sous-modules listent leur branche comme "détachée". :(
AceFunk
28

Essaye ça:

git clone --recurse-submodules

Il extrait automatiquement les données du sous-module en supposant que vous avez déjà ajouté les sous-modules au projet parent.

nweiler
la source
37
Notez que --recurse-submoduleset --recursivesont des alias équivalents .
Joel Purra
@SuperUberDuper dans ce cas, vous pouvez faire git submodule update --init --recursivecomme expliqué dans cette réponse
Enrico
25

Je pense que vous pouvez suivre 3 étapes:

git clone
git submodule init
git submodule update
muhammad ali e
la source
21

réponse tardive

// git CLONE INCLUDE-SUBMODULES ADDRESS DESTINATION-DIRECTORY
git clone --recursive https://[email protected]/USERNAME/REPO.git DESTINATION_DIR

Comme je viens de passer une heure à tripoter avec un ami: même si vous avez des droits d'administrateur sur BitBucket, clonez toujours le référentiel ORIGINAL et utilisez le mot de passe de celui qui possède le dépôt. Ennuyeux de découvrir que vous avez rencontré ce minetrap: P

kaiser
la source
C'est exactement ce à quoi je fais face. Alors, dites-vous que toute personne qui doit développer sur un référentiel bitbucket qui a des sous-modules doit utiliser les informations d'identification du créateur du référentiel? Blech.
jsleuth
@jsleuth Semble donc - ça craint BIG TIME ... et je le sais.
kaiser
Cela ressemble à un bug. L'avez-vous signalé à Bitbucket?
Mathias Bynens
@MathiasBynens Avez-vous rencontré ce problème? C'est un an et demi plus tard et je ne sais pas si c'est toujours le cas.
kaiser
4
Il ne répond pas de manière descriptive à la question OP, mais détaille un bogue sans rapport avec Bitbucket; qui, soit dit en passant, pourrait simplement être raccourci pour "utiliser l'authentification par clé SSH".
Treffynnon
18

Essayez ceci pour inclure des sous-modules dans le référentiel git.

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

ou

git clone --recurse-submodules
radhey shyam
la source
18

Vous pouvez utiliser l' --recursiveindicateur lors du clonage d'un référentiel. Ce paramètre force git à cloner tous les sous-modules définis dans le référentiel.

git clone --recursive [email protected]:your_repo.git

Après le clonage, les branches des sous-modules peuvent parfois être modifiées, exécutez donc cette commande après:

git submodule foreach "git checkout master"
Ahmad Azimi
la source
17

[Réponse rapide]

Après avoir cloné le référentiel parent (qui contenait un référentiel de sous-module), procédez comme suit:

git submodule update --init --recursive
Benyamin Jafari
la source
11

La recherche parallèle de sous-modules vise à réduire le temps nécessaire pour récupérer un référentiel et tous ses sous-modules associés en permettant la récupération de plusieurs référentiels à la fois. Cela peut être accompli en utilisant la nouvelle option --jobs, par exemple:

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

Selon l'équipe de Git, cela peut considérablement accélérer la mise à jour des référentiels contenant de nombreux sous-modules. Lorsque vous utilisez --recurse-submodules sans la nouvelle option --jobs, Git récupère les sous-modules un par un.

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

Long Nguyen
la source
8

J'ai eu le même problème pour un référentiel GitHub. Mon compte n'avait pas de clé SSH. Le processus est

  1. Générer une clé SSH
  2. Ajouter une nouvelle clé SSH à votre compte GitHub

Ensuite, vous pouvez cloner le référentiel avec des sous-modules ( git clone --recursive YOUR-GIT-REPO-URL)

ou

Exécutez git submodule initet git submodule updatepour récupérer des sous-modules dans un référentiel déjà cloné.

Erreur fatale
la source
Oui, c'est une Permission denied (publickey). fatal: Could not read from remote repository.erreur
Ender
5

Essaye ça.

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

Si vous avez ajouté le sous-module dans une branche, assurez-vous de l'ajouter à la commande clone.

Himeshika96
la source
5

S'il s'agit d'un nouveau projet, vous pouvez simplement faire comme ceci:

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

S'il est déjà installé, alors:

$ cd YourProjectName (for the cases you are not at right directory) 
$ git submodule init
$ git submodule update
nzrytmn
la source