web-dev-qa-db-fra.com

Mise à jour du sous-module Git

Je ne vois pas très bien ce que cela signifie (dans la documentation = mise à jour du sous-module Git ):

... fera en sorte que les sous-modules HEAD soient détachés, à moins que --rebase ou --merge ne soit spécifié ...

Comment --rebase/--merge change les choses?

Mon principal cas d’utilisation consiste à créer un ensemble de référentiels centraux que je vais intégrer via des sous-modules dans d’autres référentiels. J'aimerais pouvoir améliorer ces référentiels centraux, soit directement à leur emplacement d'origine, soit à partir de leurs référentiels d'intégration (ceux qui les utilisent via un sous-module).

  • À partir de ces sous-modules, puis-je créer des branches/modifications et utiliser Push/Pull comme je le ferais dans des référentiels classiques, ou faut-il rester prudent?
  • Comment puis-je faire avancer le commit référencé du sous-module de say (tagged) 1.0 à 1.1 (même si la tête du référentiel d'origine est déjà à 2.0), ou choisir le commit de la branche utilisé?
227
deepblue

Cette page GitPro résume bien la conséquence d'une mise à jour de sous-module git

Lorsque vous exécutez _git submodule update_, il extrait la version spécifique du projet, mais pas dans une branche. Cela s'appelle avoir une tête détachée - cela signifie que le fichier HEAD pointe directement sur un commit, pas sur une référence symbolique.
Le ​​problème est que vous ne voulez généralement pas travailler dans un environnement isolé, car il est facile de perdre des modifications.
Si vous effectuez une mise à jour initiale du sous-module, validez-le dans ce répertoire sans créer de branche dans laquelle travailler, puis exécutez à nouveau la mise à jour du sous-module git à partir du superprojet sans avoir été validée entre-temps, Git écrasera vos modifications sans vous en informer. . Techniquement, vous ne perdrez pas le travail, mais aucune branche ne le signalera. Il sera donc difficile de le récupérer.


Note mars 2013:

Comme indiqué dans " dernière mise à jour du sous-module git ", un sous-module peut désormais suivre (git1.8.2) une branche.

_# add submodule to track master branch
git submodule add -b master [URL to Git repo];

# update your submodule
git submodule update --remote 
# or (with rebase)
git submodule update --rebase --remote
_

Voir " git submodule update --remote_ VS _git pull ".

MindTooth 's answer illustre une mise à jour manuelle (sans configuration locale):

_git submodule -q foreach git pull -q Origin master
_

Dans les deux cas, les références des sous-modules seront modifiées (le --- gitlink, un entrée spéciale dans l'index du référant parent ), et vous devrez ajouter, commettre et pousser lesdites références à partir du référentiel principal.
La prochaine fois que vous clonerez ce référentiel parent, il remplira les sous-modules pour refléter ces nouvelles références SHA1.

Le reste de cette réponse détaille la fonctionnalité de sous-module classique (référence à un fixed commit, qui est le point global derrière la notion de sous-module).


Pour éviter ce problème, créez une branche lorsque vous travaillez dans un répertoire de sous-modules avec git checkout -b work ou quelque chose d'équivalent. Lorsque vous effectuez la mise à jour du sous-module une deuxième fois, le travail est rétabli, mais au moins vous avez un pointeur sur lequel revenir.

Changer de branche avec des sous-modules peut aussi être difficile. Si vous créez une nouvelle branche, ajoutez un sous-module à cet emplacement, puis revenez dans une branche sans ce sous-module. Le répertoire du sous-module est toujours un répertoire non suivi:


Alors, pour répondre à vos questions:

puis-je créer des branches/modifications et utiliser Push/Pull comme je le ferais dans les opérations de pension ordinaires, ou y a-t-il des points à surveiller?

Vous pouvez créer une branche et effectuer des modifications.

AVERTISSEMENT (de Tutoriel de sous-module Git ): publiez toujours (modifiez) le changement de sous-module avant de publier (modifiez) le changement dans le superprojet qui le référence. Si vous oubliez de publier le changement de sous-module, les autres utilisateurs ne pourront pas cloner le référentiel.

comment pourrais-je faire avancer le sous-module référencé commit de say (tagged) 1.0 à 1.1 (même si la tête du référentiel d'origine est déjà à 2.0)

La page " Comprendre les sous-modules " peut aider

Les sous-modules Git sont mis en œuvre à l'aide de deux pièces mobiles:

  • le fichier _.gitmodules_ et
  • un type spécial d'objet d'arbre.

Ensemble, ils triangulent une révision spécifique d'un référentiel spécifique qui est extraite dans un emplacement spécifique de votre projet.


Depuis le page du sous-module git

vous ne pouvez pas modifier le contenu du sous-module à partir du projet principal

100% correct: vous ne pouvez pas modifier un sous-module, ne vous référez qu'à l'un de ses commits.

C'est pourquoi, lorsque vous modifiez un sous-module à partir du projet principal, vous:

  • besoin de valider et Push dans le sous-module (au module en amont), et
  • puis montez dans votre projet principal et réengagez (pour que ce projet principal fasse référence au nouveau sous-module commit que vous venez de créer et de pousser)

Un sous-module vous permet d’avoir un développement approche par composants, où le projet principal fait uniquement référence à des validations spécifiques d’autres composants (ici, "autres référentiels Git déclarés en tant que sous-modules"). ").

Un sous-module est un marqueur (commit) vers un autre référentiel Git qui n'est pas lié au cycle de développement principal du projet: il (le "autre" référentiel Git) peut évoluer indépendamment.
Il appartient au projet principal de choisir dans cet autre dépôt l’engagement dont il a besoin.

Cependant, si vous voulez, par commodité , ==, modifier un de ces sous-modules directement à partir de votre projet principal, Git vous permet de le faire, à condition que en premier == publie ces modifications de sous-modules dans son référentiel Git d'origine, et then validez votre projet principal en vous référant à un new version dudit sous-module.

Mais l’idée principale demeure: faire référence à des composants spécifiques qui:

  • ont leur propre cycle de vie
  • ont leur propre jeu de balises
  • avoir leur propre développement

La liste des commits spécifiques auxquels vous vous référez dans votre projet principal définit votre configuration (c'est ce que Configuration La gestion est une question de savoir-faire, y compris Système de contrôle de version )

Si un composant pouvait réellement être développé en même temps en tant que votre projet principal (car toute modification sur le projet principal impliquerait la modification du sous-répertoire, et inversement), alors ce ne serait plus un "sous-module", mais une fusion de sous-arbres (également présentée dans la question Transfert de la base de code héritée de cvs vers un référentiel distribué ), reliant ensemble l'historique des deux repo Git.

Est-ce que cela aide à comprendre la vraie nature des sous-modules de Git?

289
VonC

Pour mettre à jour chaque sous-module, vous pouvez appeler la commande suivante (à la racine du référentiel):

git submodule -q foreach git pull -q Origin master

Vous pouvez supprimer l'option - q pour suivre l'ensemble du processus.

132
MindTooth

Pour adresser l'option --rebase vs. --merge:

Supposons que vous ayez le super référentiel A et le sous-module B et que vous souhaitiez effectuer certains travaux dans le sous-module B. Vous avez fait vos devoirs et vous savez qu'après avoir appelé

git submodule update

vous êtes dans un état HEAD-less, il est donc difficile de revenir aux commits que vous faites à ce stade. Vous avez donc commencé à travailler sur une nouvelle branche du sous-module B

cd B
git checkout -b bestIdeaForBEver
<do work>

Pendant ce temps, quelqu'un d'autre dans le projet A a décidé que la dernière et la plus grande version de B est vraiment ce que A mérite. Par habitude, vous fusionnez les modifications les plus récentes et mettez à jour vos sous-modules.

<in A>
git merge develop
git submodule update

Oh non! Vous êtes à nouveau dans un état sans tête, probablement parce que B pointe maintenant vers le SHA associé au nouveau conseil de B, ou à un autre commit. Si seulement vous aviez:

git merge develop
git submodule update --rebase

Fast-forwarded bestIdeaForBEver to b798edfdsf1191f8b140ea325685c4da19a9d437.
Submodule path 'B': rebased into 'b798ecsdf71191f8b140ea325685c4da19a9d437'

Maintenant, la meilleure idée de tous les temps pour B est basée sur le nouvel engagement, et plus important encore, vous êtes toujours sur votre branche de développement pour B, pas dans un état sans tête!

(Le --merge fusionnera les modifications d'avantUpdateSHA à afterUpdateSHA dans votre branche active, par opposition à la redistribution de vos modifications sur afterUpdateSHA.)

19
robinspb

Git 1.8.2 propose une nouvelle option, --remote, qui activera exactement ce comportement. Fonctionnement

git submodule update --rebase --remote

récupérera les dernières modifications en amont dans chaque sous-module, les rebasonnera et vérifiera la dernière révision du sous-module. Comme la documentation le dit:

--éloigné

Cette option n'est valide que pour la commande de mise à jour. Au lieu d'utiliser le SHA-1 enregistré du superprojet pour mettre à jour le sous-module, utilisez le statut de la branche de suivi à distance du sous-module.

Cela équivaut à exécuter git pull dans chaque sous-module, ce qui correspond généralement exactement à ce que vous souhaitez.

(Ceci a été copié de cette réponse .)

5
Iulian Onofrei