139 votes

Quel est l'intérêt de "git submodule init" ?

Contexte

Pour alimenter les sous-modules d'un dépôt, il faut invoque généralement :

git submodule init
git submodule update

Dans cet usage, git submodule init semble ne faire qu'une seule chose : remplir .git/config avec des informations qui sont déjà dans .gitmodules .

Quel est le but de tout cela ?

Je ne pouvais pas. git submodule update utiliser simplement les informations de .gitmodules ? Cela permettrait d'éviter les deux :

  • une commande inutile ( git submodule init ) ; et
  • une duplication inutile de données ( .gitmodules le contenu dans .git/config ).

Question

Soit :

  • il existe des cas d'utilisation pour git submodule init que je ne connais pas (dans ce cas, éclairez-moi !); ou alors
  • git submodule init est une erreur qui pourrait être supprimée dans Git sans aucun dommage.

Laquelle de ces affirmations est vraie ?

122voto

Taichi Sato Points 557

Imaginons que le référentiel comporte 10 submodules et que vous ne soyez intéressé que par deux d'entre eux. Dans ce cas, vous voudrez peut-être obtenir de temps en temps des mises à jour de ces deux seuls submodules à partir du référentiel distant. git init fonctionne bien pour cela, car une fois que vous exécutez la commande git init pour ces deux sous-modules, git submodule update --remote ne s'applique qu'à eux.


Ajout d'une démonstration de deux flux de travail.

Flux de travail1 : Les sous-modules sont des bibliothèques que plusieurs projets utilisent.

Je pense que c'est l'un des cas d'utilisation les plus courants.

Vous venez de cloner "mon-projet".

git clone https://example.com/demo/my-project

Et la surface de sa structure est comme ci-dessous.

Enter image description here

Le contenu du fichier .gitmodules

[submodule "lib1"]
    path = lib1
    url = https://example.com/demo/lib1
[submodule "lib2"]
    path = lib2
    url = https://example.com/demo/lib2
[submodule "lib3"]
    path = lib3
    url = https://example.com/demo/lib3
[submodule "lib4"]
    path = lib4
    url = https://example.com/demo/lib4

Vous voulez refactoriser le code code1.js qui fait référence à lib1 et lib2, ce qui signifie que vous n'avez pas besoin de cloner et de vérifier lib3 et lib4. Il suffit donc d'exécuter la commande ci-dessous.

git submodule init lib1 lib2

Voyons maintenant le contenu de .git/config

...
[submodule "lib1"]
    active = true
    url = https://example.com/demo/lib1
[submodule "lib2"]
    active = true
    url = https://example.com/demo/lib2

Cela signifie quelque chose comme "Prêt à mettre à jour lib1 et lib2 depuis exemple.com/demo".

À ce stade, les répertoires lib1 et lib2 sont vides. Vous pouvez cloner et extraire lib1 et lib2 avec une seule commande :

git submodule update

Maintenant vous êtes capable de refactoriser code1.js sans erreur d'importation.

Les sous-modules sont juste des références à certains commits. Ainsi, lorsque vous souhaitez mettre à jour les bibliothèques vers de nouvelles versions, vous devez mettre à jour les références. Vous pouvez le faire avec la commande suivante.

git submodule update --remote

Vous pouvez maintenant voir combien il est utile de n'initialiser que les sous-modules dont vous avez besoin.

Flux de travail 2 : Chaque sous-module est un projet et un grand projet supérieur les inclut.

Je suis un fan de ça.

Vous clonez "main-project".

git clone https://example.com/demo/main-project

Et la surface de sa structure est comme ci-dessous.

Enter image description here

Vous pouvez voir un répertoire nommé "shared". Il y a une règle dans ce workflow : si vous voulez utiliser les codes partagés de main-project dans votre projet, vous devez créer le projet comme un sous-module de main-project.

J'aime mettre les classes d'entités dans le répertoire partagé comme ci-dessous.

Enter image description here

Pour en revenir au flux de travail des submodules, le contenu du fichier .gitmodules ressemble à ce qui suit.

[submodule "sub-project1"]
    path = sub-project1
    url = https://example.com/demo/sub-project1
[submodule "sub-project2"]
    path = sub-project2
    url = https://example.com/demo/sub-project2
[submodule "sub-project3"]
    path = sub-project3
    url = https://example.com/demo/sub-project3
[submodule "sub-project4"]
    path = sub-project4
    url = https://example.com/demo/sub-project4

Cette fois, vous voulez remanier du code dans le répertoire partagé du projet principal et vous savez que seuls les sous-projets 1 et 2 font référence au code partagé, ce qui signifie que vous n'avez pas besoin de cloner et de vérifier les sous-projets 3 et 4. Il suffit donc d'exécuter la commande ci-dessous.

git submodule init sub-project1 sub-project2

Et comme je l'ai mentionné dans le workflow1, vous devez exécuter la commande ci-dessous pour les cloner et les vérifier.

git submodule update

Est-ce que je ferais git submodule update --remote dans ce cas ? Ou dois-je même initier et mettre à jour les submodules pour remanier le code dans le répertoire partagé ? Oui, parce que vous devez exécuter des tests dans les submodules après avoir remanié le code partagé et si une mise à jour des submodules est validée et poussée vers le référentiel distant pendant que vous remaniez le code, vous devez l'obtenir par le biais de la fonction git submodule update --remote .

1 votes

Merci de souligner que git submodule init pourrait être utile dans ce cas d'utilisation. Je ne l'ai pas encore essayé, mais j'ai upvoted votre réponse pour m'avoir fait réfléchir plus largement sur les flux de travail des submodules git :) Pourriez-vous ajouter un bloc de code illustrant le flux de travail auquel vous avez fait allusion ? Je pense que cela rendrait la réponse encore plus précieuse pour la communauté. Merci encore :)

1 votes

Merci de corriger mon anglais. J'ai ajouté deux flux de travail. Mais je ne suis pas sûr que cela aide quelqu'un.

0 votes

Si vous avez d'autres sous-modules et que vous souhaitez simplement initier et mettre à jour certains sous-modules spécifiques, le flux de travail devient alors le suivant : [git submodule init -- ./lib1 ./lib2] et [git submodule update --remote --recursive -- ./lib1 ./lib2]. Vous pouvez également utiliser [--merge] ou [--rebase] avec la commande update mais lisez d'abord ce qu'ils font car ils peuvent éviter un checkout à tête détachée au risque d'altérer leur historique si HEAD n'est pas sur la bonne branche pendant la mise à jour. Pour le moment, vous pouvez corriger l'état de tête détachée avec [git submodule foreach "git checkout master && git pull"] (les submodules sont si amusants et faciles à utiliser xD).

36voto

sampablokuper Points 1286

Lire le git submodule documentation il y a est un cas d'utilisation qui justifie ostensiblement l'existence de git submodule init comme une commande autonome.

Si un utilisateur qui a cloné un référentiel souhaite utiliser une URL différente pour un sous-module que celle spécifiée par le référentiel amont, alors cet utilisateur peut le faire :

git submodule init
vim .git/config # Alter submodule URL as desired, without changing .gitmodules
                # or polluting history.
git submodule update

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X