Mettre à jour un sous-module avec la dernière validation

269

J'ai un projet A qui est une bibliothèque et il est utilisé dans un projet B.

Les deux projets A et B ont un référentiel séparé sur github MAIS à l'intérieur de B, nous avons un sous-module de A.

J'ai édité quelques classes sur la bibliothèque, qui est dans le repo A, j'ai poussé sur le repo distant, donc la bibliothèque (repo A) est mise à jour.

Ces mises à jour ne reflètent pas la "référence" (le sous-module) auquel le sous-module fait référence à un commit précédent .... que dois-je faire pour mettre à jour le sous-module sur git?

graisse
la source

Réponses:

358

Entrez dans le répertoire du sous-module:

cd projB/projA

Tirez le référentiel de votre projet A ( ne mettra pas à jour le statut git de votre parent, projet B):

git pull origin master

Revenez au répertoire racine et vérifiez la mise à jour:

cd ..
git status

Si le sous-module a été mis à jour auparavant, il affichera quelque chose comme ci-dessous:

# Not currently on any branch.
# Changed but not updated:
#   (use "git add ..." to update what will be committed)
#   (use "git checkout -- ..." to discard changes in working directory)
#
#       modified:   projB/projA (new commits)
#

Ensuite, validez la mise à jour:

git add projB/projA
git commit -m "projA submodule updated"

METTRE À JOUR

Comme l'a souligné @paul, depuis git 1.8, nous pouvons utiliser

git submodule update --remote --merge

pour mettre à jour le sous-module vers la dernière validation à distance. Ce sera pratique dans la plupart des cas.

Kjuly
la source
35
BTW, si vous n'êtes pas le propriétaire du sous-module, vous pouvez simplement le faire git submodule updatelorsque quelqu'un a mis à jour le projet (vous obtiendrez un nouvel ID de validation).
Kjuly
je possède le repo principal du sous-module (proj A) mais je suis un committer dans le proj B.
fat
@Kjuly Après le commit, comment le pousser vers la télécommande? Est-ce juste git push?
KR29
1
@ KR29 à droite, et le cmd complet est git push <remote> <branch>, par exemple git push origin dev.
Kjuly
2
git submodule updatene fonctionne sans drapeaux que lorsqu'un commit a été tiré (dans le projet B) qui met à jour les références des sous-modules en question (projet A). Pour mettre à jour le projet B afin de référencer la HEADbranche de suivi à distance du projet A, vous devrez procéder git submodule update --remote --mergecomme indiqué dans la réponse de Paul Hatcher ci-dessous.
Ben Burns
109

Depuis git 1.8 vous pouvez faire

git submodule update --remote --merge

Cela mettra à jour le sous-module vers la dernière validation à distance. Vous devrez ensuite valider la modification pour que le gitlink dans le référentiel parent soit mis à jour

git commit

Et puis poussez les modifications car sans cela, l'identité SHA-1 pointant vers le sous-module ne sera pas mise à jour et donc la modification ne sera visible par personne d'autre.

Paul Hatcher
la source
Même si je le fais, git committout le monde ne le voit toujours pas. On branch master Your branch is up-to-date with 'origin/master'. Changes not staged for commit: modified: SubmoduleA (new commits) modified: SubmoduleB (new commits)
Max N
1
Avez-vous fait un "git push" après votre commit, gardez à l'esprit que commit ne change que votre dépôt local, vous devez le pousser vers la télécommande pour que tout le monde le voit
Paul Hatcher
Absent de cette réponse (mais noté dans les autres réponses ci-dessous): le ou les sous-modules mis à jour doivent être mis en scène git addavant de s'engager.
joshng
1
@joshng Je pense que tous ceux qui sont au point de travailler sur des sous-modules comprendraient cela. C'est le seul post qui m'a aidé, merci beaucoup.
Husk Rekoms
38

Si vous mettez à jour un sous-module et que vous vous y engagez, vous devez vous rendre au référentiel contenant ou supérieur et y ajouter la modification.

git status

affichera quelque chose comme:

modified:
   some/path/to/your/submodule

Le fait que le sous-module n'est pas synchronisé peut également être observé avec

git submodule

la sortie affichera:

+afafaffa232452362634243523 some/path/to/your/submodule

Le signe plus indique que votre sous-module pointe vers l'endroit où le référentiel supérieur s'attend à ce qu'il pointe.

ajoutez simplement cette modification:

git add some/path/to/your/submodule

et engagez-le:

git commit -m "referenced newer version of my submodule"

Lorsque vous augmentez vos modifications, assurez-vous de pousser d'abord la modification dans le sous-module, puis appuyez sur la modification de référence dans le référentiel externe. De cette façon, les personnes qui mettent à jour pourront toujours exécuter avec succès

git submodule update

Plus d'informations sur les sous-modules peuvent être trouvées ici http://progit.org/book/ch6-6.html .

Adam Dymitruk
la source
Si vous n'en voyez pas +lorsque vous exécutez git submodule, assurez-vous d'avoir initialisé et importé les sous-modules. Les commandes pour cela sont git submodule initet git submodule update, respectivement.
fureigh
19

Version à ligne unique

git submodule foreach "(git checkout master; git pull; cd ..; git add '$path'; git commit -m 'Submodule Sync')"
Andy Webov
la source
2

Quelques-unes des autres réponses recommandent de fusionner / valider dans le répertoire du sous-module, ce qui peut devenir un peu compliqué pour l'OMI.

En supposant que le serveur distant est nommé originet que nous voulons la masterbranche du ou des sous-modules, j'ai tendance à utiliser:

git submodule foreach "git fetch && git reset --hard origin/master"

Remarque: Cela effectuera une réinitialisation matérielle sur chaque sous-module - si vous ne le souhaitez pas, vous pouvez passer --hardà --soft.

XtraSimplicity
la source
1

Mon projet devrait utiliser la «dernière» pour le sous-module. Sur Mac OSX 10.11, git version 2.7.1, je n'avais pas besoin d'aller «dans» mon dossier de sous-module pour collecter ses validations. J'ai simplement fait un

git pull --rebase 

au niveau supérieur, et il a correctement mis à jour mon sous-module.

AnneTheAgile
la source
0

La réponse d'Andy a fonctionné pour moi en s'échappant de $ path:

git submodule foreach "(git checkout master; git pull; cd ..; git add \$path; git commit -m 'Submodule Sync')"
Miguel Fernandes Muldy
la source
La raison pour laquelle la réponse de @Andy Webov n'a pas nécessité de s'échapper est probablement parce qu'ils ont utilisé des guillemets simples autour du chemin, par exemple. '$path'
S0AndS0