finalement, tout projet logiciel intéressant dépendra d’un autre projet, bibliothèque ou framework. Git fournit des sous-modules pour aider à cela. Les sous-modules vous permettent d’inclure ou d’intégrer un ou plusieurs référentiels en tant que sous-dossier dans un autre référentiel.
Pour de nombreux projets, les sous-modules ne sont pas la meilleure réponse (plus à ce sujet ci-dessous), et même à leur meilleur, travailler avec des sous-modules peut être délicat, mais commençons par Regarder un exemple simple.,
Ajouter un sous-module
disons que vous travaillez sur un projet baptisé Slingshot. Vous avez le code pour y-shaped stick
et un rubber-band
.
photo flickr partagée par young@art sous licence Creative Commons ( BY)
en même temps, dans un autre dépôt, vous avez un autre projet appelé Rock—c’est juste une bibliothèque Génériquerock
, mais vous pensez que ce serait parfait pour Slingshot.
Vous pouvez ajouter la balise rock
comme un sous-module de slingshot
., Dans le référentiel slingshot
:
à ce stade, vous aurez un dossier rock
à l’intérieur de slingshot
, mais si vous deviez jeter un coup d’œil à l’intérieur de ce dossier, en fonction de votre version git, vous pourriez voir nothing rien.,
Les nouvelles versions de Git le feront automatiquement, mais les anciennes versions vous demanderont de dire explicitement à Git de télécharger le contenu de rock
:
Si tout semble bon, vous pouvez valider cette modification et vous aurez un rock
slingshot
dépôt avec tout le contenu du rock
dépôt.,
Sur GitHub, le rock
icône de dossier aura un peu de voyant indiquant que c’est un sous-module:
Et en cliquant sur la balise rock
dossier va vous prendre pour le rock
référentiel.
C’est elle! Vous avez intégré le référentielrock
dans le référentielslingshot
. Vous pouvez interagir avec tout le contenu de rock
comme s’il s’agissait d’un dossier à l’intérieur deslingshot
(car c’est le cas).,
sur la ligne de commande, les commandes git émises à partir de slingshot
(ou de l’un des autres dossiers, rubber-band
Et y-shaped-stick
) fonctionneront sur le « référentiel parent”, slingshot
, mais les commandes que vous émettez à partir du dossier rock
fonctionneront uniquement sur le référentiel rock
:
rejoindre un projet en utilisant des sous-modules
maintenant, disons que vous êtes un nouveau collaborateur rejoignant le projet Slingshot., Vous commenceriez par exécuter git clone
pour télécharger le contenu du référentiel slingshot
. À ce stade, si vous deviez jeter un coup d’œil dans le dossier rock
, vous ne verriez nothing rien.
encore une fois, Git s’attend à ce que nous lui demandions explicitement de télécharger le contenu du sous-module., Vous pouvez également utiliser git submodule update --init --recursive
ici, mais si vous clonez slingshot
pour la première fois, vous pouvez utiliser une commande modifiée clone
pour vous assurer de tout Télécharger, y compris les sous-modules:
passer aux sous-modules
Il peut être un peu difficile de prendre un sous-dossier existant et de le transformer en dépendance externe. Regardons un exemple.
Vous êtes sur le point de démarrer un nouveau projet—un Magic roll-back can–qui nécessite également unrubber-band
., Prenons le rubber-band
que vous avez construit pour slingshot
, divisons-le en un référentiel autonome, puis intégrez-le dans les deux projets via des sous-modules.
Vous pouvez tout prendre du dossierrubber-band
du projet Slingshot et l’extraire dans un nouveau référentiel et même maintenir l’historique des commits.
commençons par extraire le contenu de la balise rubber-band
le dossier de slingshot
., Vous pouvez utiliser git filter-branch
pour ce faire, vous laissant avec seulement les changements liés à la rubber-band
. La commande git filter-branch
réécrira l’historique de notre référentiel, ce qui donnera l’impression que le dossier rubber-band
avait été son propre référentiel depuis le début. Pour plus d’informations sur git filter-branch
, consultez cet article.
La première étape est de faire une copie de slingshot
travailler sur l’objectif final est de rubber-band
que pour son propre référentiel, afin de les laisser slingshot
comme c’est., Vous pouvez utiliser cp
par -r
récursive de copier l’intégralité de l’élément slingshot
dossier vers un nouveau dossier rubber-band
.,
Il ressemble rubber-band
est juste un autre slingshot
, mais maintenant, à partir de la balise rubber-band
référentiel, run git filter-branch
:
À ce stade, vous aurez un dossier rubber-band
, qui est un référentiel qui ressemble au Projet de lance-pierre, mais il a seulement les fichiers et commettre l’histoire de la balise rubber-band
dossier.,
puisque vous l’avez copié à partir deslingshot
, le nouveau référentiel aura toujours toutes les branches de suivi à distance que vous avez configurées quand il étaitslingshot
. Vous ne voulez pas pousser rubber-band
retour sur le slingshot
. Vous souhaitez pousser cela vers un nouveau référentiel.
créez un nouveau référentiel pourrubber-band
sur GitHub, puis mettez à jour la télécommande pourrubber-band
., En supposant que vous appeliez le origin
distant, vous pourriez:
alors vous pouvez publier le nouveau « module générique de bande élastique” avecgit push
.,
Maintenant que vous avez séparé rubber-band
dans son propre référentiel, vous devez supprimer l’ancien rubber-band
dossier à partir de la balise slingshot
référentiel:
Ensuite mettre à jour slingshot
utiliser rubber-band
comme un sous-module:
Comme nous l’avons vu auparavant, quand nous étions en ajoutant rock
, nous avons maintenant un dépôt-dans-un-référentiel., Trois référentiels, en fait: le « parent” référentiel slingshot
, ainsi que les deux « sous” les référentiels, rock
et rubber-band
.
de plus, si nous replongeons dans l’historique deslingshot
, nous verrons les commits que nous avons initialement effectués dansrubber-band
à l’époque où il s’agissait d’un dossier—la suppression du dossier n’effaçait aucun historique., Cela peut parfois être un peu déroutant-puisque le référentielrubber-band
« enfant” a une version copiée et modifiée de ces anciens commitsslingshot
, il peut parfois avoir l’impression que vous avez déjà vu.
Malheureusement, tout collaborateur qui tire slingshot
à ce point va être vide rubber-band
dossier., Vous voudrez peut-être rappeler à vos collaborateurs d’exécuter cette commande pour s’assurer qu’ils ont tout le contenu du sous-module:
vous voudrez également ajouter le rubber-band
sous-module à magic roll-back can
. Heureusement, tout ce que vous devez faire est de suivre la même procédure que celle utilisée précédemment lorsque vous avez ajouté rock
à slingshot
, dans « Ajout d’un sous-module. »
conseils sur l’utilisation de sous-modules (ou non)
- avant d’ajouter un référentiel en tant que sous-module, Vérifiez d’abord si vous avez une meilleure alternative disponible., Les sous-modules Git fonctionnent assez bien pour les cas simples, mais de nos jours, il existe souvent de meilleurs outils disponibles pour gérer les dépendances que ce que les sous-modules Git peuvent offrir. Les langues modernes comme Go ont des systèmes de gestion des dépendances conviviaux et compatibles avec Git intégrés dès le début. D’autres, comme rubygems de Ruby, noeud.npm DE JS, ou CocoaPods de Cocoa et Carthage, ont été ajoutés par la communauté de programmation. Même les développeurs frontaux ont des outils comme Bower pour gérer les bibliothèques et les frameworks pour JavaScript et CSS côté client.
- rappelez-vous que Git ne télécharge pas le contenu du sous-module par défaut., Si vous ajoutez un sous-module à un projet existant, assurez-vous que toute personne qui travaille sur le projet sait qu’elle doit exécuter des commandes comme
git submodule update
Etgit clone --recursive
pour s’assurer qu’elle obtient tout—cela inclut tout service de déploiement ou de test automatisé qui pourrait être impliqué dans le projet! Nous vous recommandons d’utiliser quelque chose comme nos « Scripts to Rule Them All” pour vous assurer que tous les collaborateurs et services ont accès au même contenu de référentiel partout. - Les sous-modules exigent que vous équilibriez soigneusement la cohérence et la commodité., La configuration utilisée ici préfère fortement la cohérence, au prix d’un peu de commodité. Il est généralement préférable de verrouiller les sous-modules d’un projet sur un SHA spécifique, afin que tous les collaborateurs reçoivent le même contenu. Mais cette configuration rend également difficile pour les développeurs du référentiel « parent » d’apporter des modifications au référentiel sous-module.
- rappelez-vous que les collaborateurs ne verront pas automatiquement les mises à jour des sous—modules-Si vous mettez à jour un sous-module, vous devrez peut-être rappeler à vos collègues d’exécuter
git submodule update
ou ils verront probablement un comportement étrange., - gérer des référentiels dynamiques, en évolution rapide ou fortement co-dépendants avec des sous-modules peut rapidement devenir frustrant. Cet article était axé sur les relations de référentiel parent-enfant simples et relativement statiques. Un prochain post de suivi détaillera certaines stratégies pour aider à gérer des flux de travail de sous-modules plus complexes.