J'ai un projet avec un sous-module Git. Il provient d'une URL ssh: // ... et se trouve sur la validation A. La validation B a été poussée vers cette URL, et je veux que le sous-module récupère la validation et la modifie.
Maintenant, je crois que cela git submodule update
devrait le faire, mais ce n'est pas le cas. Il ne fait rien (pas de sortie, code de sortie de réussite). Voici un exemple:
$ mkdir foo
$ cd foo
$ git init .
Initialized empty Git repository in /.../foo/.git/
$ git submodule add ssh://user@host/git/mod mod
Cloning into mod...
user@host's password: hunter2
remote: Counting objects: 131, done.
remote: Compressing objects: 100% (115/115), done.
remote: Total 131 (delta 54), reused 0 (delta 0)
Receiving objects: 100% (131/131), 16.16 KiB, done.
Resolving deltas: 100% (54/54), done.
$ git commit -m "Hello world."
[master (root-commit) 565b235] Hello world.
2 files changed, 4 insertions(+), 0 deletions(-)
create mode 100644 .gitmodules
create mode 160000 mod
# At this point, ssh://user@host/git/mod changes; submodule needs to change too.
$ git submodule init
Submodule 'mod' (ssh://user@host/git/mod) registered for path 'mod'
$ git submodule update
$ git submodule sync
Synchronizing submodule url for 'mod'
$ git submodule update
$ man git-submodule
$ git submodule update --rebase
$ git submodule update
$ echo $?
0
$ git status
# On branch master
nothing to commit (working directory clean)
$ git submodule update mod
$ ...
J'ai également essayé git fetch mod
, qui semble faire une extraction (mais ne peut pas, car il ne demande pas de mot de passe!), Mais git log
et git show
nie l'existence de nouveaux commits. Jusqu'à présent, je viens de rm
modifier le module et de le rajouter, mais c'est à la fois faux en principe et fastidieux dans la pratique.
git
git-submodules
git-pull
Thanatos
la source
la source
--remote
option, il serait peut-être utile de marquer cela comme la réponse acceptée plutôt que l'approche "à la main" dans la réponse de Jason?--remote
est définitivement une meilleure solution à ce stade, et puisque cette question a été liée à un Github Gist sur les sous-modules, je pense qu'il serait préférable pour les lecteurs entrants de voir la nouvelle réponse.hunter2
mot de passe: o)Réponses:
La
git submodule update
commande indique en fait à Git que vous voulez que vos sous-modules vérifient chacun le commit déjà spécifié dans l'index du superprojet. Si vous souhaitez mettre à jour vos sous-modules vers la dernière validation disponible à partir de leur télécommande, vous devrez le faire directement dans les sous-modules.Donc en résumé:
Ou, si vous êtes une personne occupée:
la source
git submodule foreach git pull
git submodule foreach git pull origin master
.git submodule foreach --recursive git pull origin master
.-a
commutateurgit commit
"Tell [s] the command to stage automatiquement les fichiers qui ont été modifiés et supprimés, mais les nouveaux fichiers dont vous n'avez pas parlé à Git ne sont pas affectés."Git 1.8.2 propose une nouvelle option
--remote
, qui activera exactement ce comportement. Fonctionnementrécupérera les dernières modifications en amont dans chaque sous-module, les fusionnera et vérifiera la dernière révision du sous-module. Comme le dit la documentation :
Cela revient à exécuter
git pull
dans chaque sous-module, ce qui est généralement exactement ce que vous voulez.la source
git pull
dans chaque sous-module" Pour clarifier, il n'y a pas de différence (du point de vue de l'utilisateur) entre votre réponse etgit submodule foreach git pull
?foreach git pull
les a uniquement extraits, mais n'ont pas mis à jour le pointeur du référentiel principal pour pointer vers la nouvelle validation du sous-module. Ce n'est qu'avec--remote
cela qu'il a fait pointer le dernier commit.Dans le répertoire parent de votre projet, exécutez:
Ou si vous avez des sous-modules récursifs exécutés:
Parfois, cela ne fonctionne toujours pas, car vous avez en quelque sorte des modifications locales dans le répertoire du sous-module local pendant la mise à jour du sous-module.
La plupart du temps, le changement local n'est peut-être pas celui que vous souhaitez valider. Cela peut se produire en raison d'une suppression de fichier dans votre sous-module, etc. Si c'est le cas, effectuez une réinitialisation dans votre répertoire de sous-module local et dans le répertoire parent de votre projet, exécutez à nouveau:
la source
Votre projet principal pointe vers un commit particulier auquel le sous-module doit se trouver.
git submodule update
essaie de vérifier ce commit dans chaque sous-module qui a été initialisé. Le sous-module est vraiment un référentiel indépendant - il suffit de créer un nouveau commit dans le sous-module et de pousser cela ne suffit pas. Vous devez également ajouter explicitement la nouvelle version du sous-module dans le projet principal.Donc, dans votre cas, vous devriez trouver le bon commit dans le sous-module - supposons que c'est la pointe de
master
:Revenez maintenant au projet principal, mettez en scène le sous-module et validez que:
Poussez maintenant votre nouvelle version du projet principal:
À partir de ce moment, si quelqu'un met à jour son projet principal, alors
git submodule update
il mettra à jour le sous-module, en supposant qu'il a été initialisé.la source
Il semble que deux scénarios différents soient mélangés dans cette discussion:
Scénario 1
En utilisant les pointeurs de mon référentiel parent vers les sous-modules, je veux vérifier la validation dans chaque sous-module vers lequel pointe le référentiel parent, peut-être après avoir d'abord itéré tous les sous-modules et les avoir mis à jour / extraits à distance.
Ceci est, comme souligné, fait avec
Scénario 2, qui je pense est ce que vise OP
De nouvelles choses se sont produites dans un ou plusieurs sous-modules, et je veux 1) tirer ces modifications et 2) mettre à jour le référentiel parent pour pointer vers la validation HEAD (la plus récente) de ce / ces sous-modules.
Cela serait fait par
Pas très pratique, car il faudrait coder en dur n chemins vers tous les n sous-modules, par exemple dans un script pour mettre à jour les pointeurs de validation du référentiel parent.
Il serait intéressant d'avoir une itération automatisée à travers chaque sous-module, mettant à jour le pointeur du référentiel parent (à l'aide
git add
) pour pointer vers la tête du ou des sous-modules.Pour cela, j'ai réalisé ce petit script Bash:
git-update-submodules.sh
Pour l'exécuter, exécutez
Élaboration
Tout d'abord, je suppose que la branche avec le nom $ BRANCH (deuxième argument) existe dans tous les référentiels. N'hésitez pas à rendre cela encore plus complexe.
Les deux premières sections consistent à vérifier que les arguments sont là. Ensuite, je récupère les derniers éléments du référentiel parent (je préfère utiliser --ff (avance rapide) chaque fois que je fais des pulls. J'ai rebase off, BTW).
Ensuite, une initialisation de sous-module peut être nécessaire si de nouveaux sous-modules ont été ajoutés ou ne sont pas encore initialisés:
Ensuite, je mets à jour / tire tous les sous-modules:
Remarquez quelques choses: Tout d'abord, je chaîne certaines commandes Git en utilisant
&&
- ce qui signifie que la commande précédente doit s'exécuter sans erreur.Après un éventuel pull réussi (si de nouveaux éléments ont été trouvés sur la télécommande), je fais un push pour m'assurer qu'un éventuel merge-commit n'est pas laissé sur le client. Encore une fois, cela ne se produit que si un pull a réellement apporté de nouvelles choses.
Enfin, la finale
|| true
s'assure que le script continue sur les erreurs. Pour que cela fonctionne, tout dans l'itération doit être encapsulé entre guillemets et les commandes Git sont encapsulées entre parenthèses (priorité de l'opérateur).Ma partie préférée:
Itérer tous les sous-modules - avec
--quiet
, ce qui supprime la sortie «Entering MODULE_PATH». À l'aide de'echo $path'
(doit être entre guillemets simples), le chemin d'accès au sous-module est écrit en sortie.Cette liste de chemins de sous-module relatifs est capturée dans un tableau (
$(...)
) - enfin, répétez cela et faitesgit add $i
pour mettre à jour le référentiel parent.Enfin, un commit avec un message expliquant que le référentiel parent a été mis à jour. Ce commit sera ignoré par défaut, si rien n'a été fait. Poussez ceci à l'origine, et vous avez terminé.
J'ai un script qui exécute cela dans un travail Jenkins qui s'enchaîne ensuite à un déploiement automatisé planifié, et cela fonctionne comme un charme.
J'espère que cela sera utile à quelqu'un.
la source
pwd
commande imprime le «chemin absolu» approprié pour chaque sous-module présent;--recursive
s'assure que nous visitons tous les sous-modules, y compris les sous-modules dans les sous-modules -... qui peuvent être présents dans un grand projet. Les deux méthodes causer des problèmes avec les répertoires qui comprennent des espaces, par exemple/c/Users/Ger/Project\ Files/...
où la politique est de ne jamais utiliser des espaces partout dans nos projets.--remote
option.git submodule update --remote
se comporte approximativement comme le fait votre script.The remote branch used defaults to master, but the branch name may be overridden by setting the submodule.<name>.branch option in either .gitmodules or .git/config (with .git/config taking precedence).
je ne veux pas éditer .gitmodules ni .git / config chaque fois que je veux le faire dans une autre branche que master. Mais peut-être que j'ai raté quelque chose? De plus, la méthode semble imposer des fusions récursives (manquant ainsi la possibilité d'une avance rapide).Clair et simple, pour aller chercher les sous-modules:
Et maintenant, continuez à les mettre à jour vers la dernière branche principale (par exemple):
la source
Remarque, alors que la forme moderne de mise à jour des commits de sous-modules serait:
L'ancienne forme était:
Sauf que cette deuxième forme n'est pas vraiment "silencieuse".
Voir commit a282f5a (12 avril 2019) par Nguyễn Thái Ngọc Duy (
pclouds
) .(Fusionné par Junio C Hamano -
gitster
- dans commit f1c9f6c , 25 avril 2019)Et Git 2.23 (Q3 2019) corrige un autre problème: "
git submodule foreach
" ne protégeait pas les options de ligne de commande passées à la commande à exécuter correctement dans chaque sous-module, lorsque l'--recursive
option " " était en cours d'utilisation.Voir commit 30db18b (24 juin 2019) par Morian Sonnet (
momoson
) .(Fusionné par Junio C Hamano -
gitster
- en commit 968eecb , 09 juil.2019 )la source
Cela tirera tous les derniers commits.
la source
Dans mon cas, je voulais
git
mettre à jour au plus tard et en même temps re-remplir tous les fichiers manquants.Ce qui suit a restauré les fichiers manquants (
--force
ce qui ne semble pas avoir été mentionné ici), mais il n'a pas généré de nouveaux commits:git submodule update --init --recursive --force
Cela a:
git submodule update --recursive --remote --merge --force
la source
@Jason est correct dans un sens mais pas entièrement.
Il en
git submodule update
va de même pour la vérification, mais c'est pour la validation dans l'index du référentiel contenant. Il n'a pas encore connaissance du nouveau commit en amont. Allez donc dans votre sous-module, obtenez le commit que vous voulez et validez l'état du sous-module mis à jour dans le référentiel principal, puis faites legit submodule update
.la source
git submodule update
, update déplacera le sous-module vers le commit spécifié dans le HEAD actuel du superprojet. (quel que soit le commit le plus récent du superprojet, le sous-projet devrait être - ce comportement, après l'explication dans le post de Jason, me semble logique) Il semble également aller chercher, mais uniquement dans le cas où le sous-projet est sur le mauvais commit , ce qui ajoutait à ma confusion.Voici un impressionnant one-liner pour tout mettre à jour au plus tard sur master:
Merci à Mark Jaquith
la source
Si vous ne connaissez pas la branche hôte, procédez comme suit:
Il obtiendra une branche du référentiel Git principal et puis pour chaque sous-module fera un pull de la même branche.
la source
Si vous cherchez à commander une
master
branche pour chaque sous-module, vous pouvez utiliser la commande suivante à cette fin:la source