Un submodule Git est un dépôt Git imbriqué dans un autre. Le projet parent référence un commit précis du sous-dépôt, ce qui permet d’intégrer des bibliothèques, des outils ou des configurations partagées tout en gardant les historiques séparés. Ce guide couvre le workflow complet, de l’ajout à la mise à jour.
Prérequis : Remotes fondamentaux et Branches distantes.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Ajouter un submodule dans un dépôt existant et cloner avec ses submodules
- Mettre à jour un submodule vers une nouvelle version du dépôt distant
- Identifier les pièges classiques : HEAD détaché, oubli de commit, double push
- Comparer submodules et
git subtreepour choisir la bonne approche
Quand utiliser des submodules ?
Section intitulée « Quand utiliser des submodules ? »Les submodules sont utiles quand :
- Vous intégrez une bibliothèque partagée entre plusieurs projets
- Vous voulez une version figée d’une dépendance (pas toujours la dernière)
- Les dépôts doivent garder des historiques indépendants
- Chaque équipe gère son propre dépôt
Exemples concrets : un framework interne, des fichiers de configuration Terraform partagés, un thème de documentation.
Ajouter un submodule
Section intitulée « Ajouter un submodule »git submodule add https://github.com/org/lib-utils.git libs/utilsCette commande :
- Clone
lib-utilsdanslibs/utils/ - Crée (ou met à jour) le fichier
.gitmodules:
[submodule "libs/utils"] path = libs/utils url = https://github.com/org/lib-utils.git- Enregistre le commit exact du submodule dans l’index du projet parent
Commitez les changements :
git add .gitmodules libs/utilsgit commit -m "chore: ajouter lib-utils comme submodule"Cloner un projet avec submodules
Section intitulée « Cloner un projet avec submodules »En une seule commande
Section intitulée « En une seule commande »git clone --recurse-submodules https://github.com/org/mon-projet.gitSi vous avez déjà cloné
Section intitulée « Si vous avez déjà cloné »git submodule init # Enregistre les URLs depuis .gitmodulesgit submodule update # Clone les submodules au commit référencéOu en une seule commande :
git submodule update --init --recursive--recursive gère aussi les submodules imbriqués (submodules de
submodules).
Mettre à jour un submodule
Section intitulée « Mettre à jour un submodule »Récupérer la dernière version
Section intitulée « Récupérer la dernière version »-
Allez dans le dossier du submodule :
Fenêtre de terminal cd libs/utils -
Mettez à jour depuis le remote :
Fenêtre de terminal git fetchgit checkout maingit pull -
Revenez au projet parent et commitez la nouvelle référence :
Fenêtre de terminal cd ../..git add libs/utilsgit commit -m "chore: mettre à jour lib-utils vers v2.1"
Raccourci : mettre à jour tous les submodules
Section intitulée « Raccourci : mettre à jour tous les submodules »git submodule update --remoteCette commande fetch et checkout la dernière version de la branche configurée pour chaque submodule.
Pour changer la branche suivie :
git config -f .gitmodules submodule.libs/utils.branch developTravailler dans un submodule
Section intitulée « Travailler dans un submodule »Vous pouvez modifier le code du submodule directement :
-
Entrez dans le submodule et créez une branche :
Fenêtre de terminal cd libs/utilsgit switch -c fix/typo -
Modifiez, commitez :
Fenêtre de terminal git add .git commit -m "fix: corriger typo dans README" -
Poussez vers le remote du submodule :
Fenêtre de terminal git push origin fix/typo -
Revenez au projet parent et enregistrez le nouveau commit :
Fenêtre de terminal cd ../..git add libs/utilsgit commit -m "chore: avancer lib-utils (fix typo)"
--recurse-submodules partout
Section intitulée « --recurse-submodules partout »Ajoutez cette option aux commandes courantes pour ne pas oublier les submodules :
git pull --recurse-submodulesgit checkout --recurse-submodules branchegit clone --recurse-submodules urlPour l’activer par défaut :
git config --global submodule.recurse trueSupprimer un submodule
Section intitulée « Supprimer un submodule »Il n’y a pas de commande unique. Voici la procédure :
# 1. Supprimer l'entrée du staging et du dossiergit rm libs/utils
# 2. Supprimer les métadonnées internesrm -rf .git/modules/libs/utils
# 3. Commitergit commit -m "chore: supprimer le submodule lib-utils"foreach : commande sur tous les submodules
Section intitulée « foreach : commande sur tous les submodules »# Afficher le statut de tous les submodulesgit submodule foreach 'git status'
# Mettre à jour tous les submodulesgit submodule foreach 'git pull origin main'
# Stasher dans tous les submodulesgit submodule foreach 'git stash'Pièges courants
Section intitulée « Pièges courants »Le submodule est en HEAD détaché
Section intitulée « Le submodule est en HEAD détaché »Après git submodule update, le submodule est toujours en detached
HEAD (il pointe vers un commit, pas une branche). Pour travailler
dedans, créez ou checkoutez une branche :
cd libs/utilsgit switch mainmodified content (new commits) dans git status
Section intitulée « modified content (new commits) dans git status »Le projet parent voit que le submodule pointe vers un commit différent
de celui référencé. C’est normal si vous avez fait un git pull dans
le submodule. Commitez la mise à jour dans le parent :
git add libs/utilsgit commit -m "chore: avancer lib-utils"git diff montre des submodules modifiés
Section intitulée « git diff montre des submodules modifiés »# Voir les détailsgit diff --submodule
# Résumégit diff --submodule=shortPour avoir le résumé automatiquement :
git config --global diff.submodule logSubmodules vs alternatives
Section intitulée « Submodules vs alternatives »| Critère | Submodules | Subtree | Gestionnaire de paquets |
|---|---|---|---|
| Historiques | Séparés | Fusionné | Non versionné |
| Mise à jour | Manuelle (commit ref) | git subtree pull | npm update, etc. |
| Complexité | Moyenne-élevée | Moyenne | Faible |
| Clone | Nécessite --recurse | Automatique | Nécessite install |
| Contribution au sous-projet | Facile (push dans le submodule) | Possible (subtree push) | Via le repo original |
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
| Dossier submodule vide après clone | --recurse-submodules oublié | git submodule update --init --recursive |
| HEAD détaché dans le submodule | Comportement normal | git switch branche pour travailler |
reference is not a tree au clone | Commit du submodule non poussé | Pousser le submodule d’abord |
| Conflit sur la ref du submodule | Deux branches avancent le submodule | Résolvez en choisissant le bon commit |
fatal: No url found for submodule | .gitmodules absent ou corrompu | Vérifiez/recréez .gitmodules |
À retenir
Section intitulée « À retenir »- Un submodule référence un commit précis d’un dépôt externe
git submodule update --init --recursiveest la commande à retenir pour initialiser- Après
update, le submodule est en detached HEAD — normal - Poussez toujours le submodule avant le parent
submodule.recurse truesimplifie la vie au quotidien- Pour des besoins plus simples, considérez subtree