500 votes

Comment déplacer un sous-module Git existant dans un dépôt Git ?

Je voudrais changer le nom du répertoire d'un sous-module Git dans mon superprojet Git.

Supposons que j'ai l'entrée suivante dans mon fichier .gitmodules fichier :

[submodule ".emacs.d/vimpulse"]  
path = .emacs.d/vimpulse  
url = git://gitorious.org/vimpulse/vimpulse.git

Que dois-je taper pour déplacer le .emacs.d/vimpulse pour .emacs.d/vendor/vimpulse sans le supprimer d'abord (expliqué aquí y aquí ), puis de le réinsérer.

Git a-t-il vraiment besoin du chemin complet dans la balise du sous-module ?

[submodule ".emacs.d/vimpulse"]

ou est-il également possible de stocker uniquement le nom du sous-projet ?

[submodule "vimpulse"]

0 votes

REMARQUE : le PO répond à sa propre question par la phrase suivante git mv commande, juste dans la question.

0 votes

CEPENDANT, vous ne pouvez pas utiliser git mv comme ceci. Utilisez deinit puis rm comme indiqué stackoverflow.com/a/18892438/8047 .

19 votes

@Yar : au moins sur git 2.0.0, git mv fonctionne juste pour les sous-modules également, pas besoin d'autre chose.

575voto

XTaran Points 1249

Nota: Comme mentionné dans les commentaires, cette réponse fait référence aux étapes nécessaires avec les anciennes versions de Git. Git a maintenant un support natif pour le déplacement des submodules :

Depuis git 1.8.5, git mv old/submod new/submod fonctionne comme prévu et fait toute la plomberie pour vous. Vous pouvez utiliser git 1.9.3 ou une version plus récente, car elle inclut des corrections pour le déplacement des submodules.


Le processus est similaire à celui de la suppression d'un sous-module (cf. Comment supprimer un sous-module ? ) :

  1. Modifier .gitmodules et changez le chemin du sous-module de manière appropriée, et mettez-le dans l'index avec git add .gitmodules .

  2. Si nécessaire, créez le répertoire parent du nouvel emplacement du sous-module ( mkdir -p new/parent ).

  3. Déplacez tout le contenu de l'ancien vers le nouveau répertoire ( mv -vi old/parent/submodule new/parent/submodule ).

  4. Assurez-vous que Git suit ce répertoire ( git add new/parent ).

  5. Supprimez l'ancien répertoire avec git rm --cached old/parent/submodule .

  6. Déplacer le répertoire .git/modules/old/parent/submodule avec tout son contenu à .git/modules/new/parent/submodule .

  7. Modifier le .git/modules/new/parent/config assurez-vous que l'élément de l'arbre de travail pointe vers les nouveaux emplacements, donc dans cet exemple il devrait être worktree = ../../../../../new/parent/module . En général, il devrait y avoir deux autres .. que les répertoires du chemin direct à cet endroit.

  8. Modifier le fichier new/parent/module/.git assurez-vous que le chemin qu'il contient pointe vers le nouvel emplacement correct dans le projet principal. .git donc dans cet exemple gitdir: ../../../.git/modules/new/parent/submodule .

    git status La sortie ressemble à ça pour moi ensuite :

    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       modified:   .gitmodules
    #       renamed:    old/parent/submodule -> new/parent/submodule
    #
  9. Enfin, livrez les changements.

0 votes

Après cela, vous devez nettoyer manuellement vos [submodules] .git/config, n'est-ce pas ? Ou existe-t-il une commande qui permet de le faire ?

0 votes

Est-ce que c'est toujours la manière suggérée pour cela ?

0 votes

Pour information, je n'ai pas réussi à faire fonctionner ce système - peut-être manque-t-il une étape dont je ne suis pas conscient ?

293voto

phatmann Points 4153

La réponse la plus moderne, tirée du commentaire de Valloric ci-dessus :

  1. Mise à jour vers Git 1.9.3 (ou 2.18 si le sous-module contient des sous-modules imbriqués )
  2. git mv old/submod new/submod
  3. Ensuite, les .gitmodules et le répertoire des submodules sont déjà mis à disposition pour un commit (vous pouvez le vérifier avec la commande git status .)
  4. Valider les changements avec git commit et vous êtes prêt à partir !

C'est fait !

3 votes

Cela a en effet fonctionné avec 1.9.3 sauf pour un sous-module à l'intérieur du sous-module déplacé. Cela a nécessité un nettoyage manuel.

3 votes

Cela devrait déjà fonctionner dans la version 1.8.5 comme décrit dans les notes de mise à jour .

7 votes

Cette réponse devrait obtenir 1000 upvotes, j'ai presque fait un désordre avec mon repo en faisant les étapes décrites ci-dessus, vraiment StackOverflow devrait avoir un cas d'utilisation pour cette situation.

57voto

Matt Connolly Points 4851

Dans mon cas, je voulais déplacer un sous-module d'un répertoire vers un sous-répertoire, par exemple "AFNetworking" -> "ext/AFNetworking". Voici les étapes que j'ai suivies :

  1. Modifier le fichier .gitmodules en changeant le nom et le chemin du sous-module en "ext/AFNetworking".
  2. Déplacer le répertoire git du sous-module de ".git/modules/AFNetworking" vers ".git/modules/ext/AFNetworking".
  3. Déplacez la bibliothèque de "AFNetworking" vers "ext/AFNetworking".
  4. Modifiez ".git/modules/ext/AFNetworking/config" et corrigez l'élément suivant [core] worktree ligne. La mienne est passée de ../../../AFNetworking a ../../../../ext/AFNetworking
  5. Modifier "ext/AFNetworking/.git" et corriger gitdir . Le mien est passé de ../.git/modules/AFNetworking a ../../git/modules/ext/AFNetworking
  6. git add .gitmodules
  7. git rm --cached AFNetworking
  8. git submodule add -f <url> ext/AFNetworking

Enfin, j'ai vu dans le statut git :

matt$ git status
# On branch ios-master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   .gitmodules
#   renamed:    AFNetworking -> ext/AFNetworking

Et voilà. L'exemple ci-dessus ne change pas la profondeur du répertoire, ce qui fait une grande différence dans la complexité de la tâche, et ne change pas le nom du sous-module (ce qui n'est peut-être pas vraiment nécessaire, mais je l'ai fait pour être cohérent avec ce qui se passerait si j'ajoutais un nouveau module à ce chemin).

4 votes

Merci Matt. J'étais perdu sur la réponse acceptée. Merci d'avoir couvert plus que le cas de base. Cela a marché comme sur des roulettes.

0 votes

Vous n'avez pas besoin de remuer les chemins .git/modules, ni de changer le nom du sous-module (comme le mentionnent arand et Bob Bell). Bien que cela puisse rendre les choses plus propres.

0 votes

N'oubliez pas d'effectuer les étapes 2, 3, 4 et 5 de manière récursive pour tout sous-sous-module.

27voto

Mark Mikofski Points 2503

_[Mise à jour : 2014-11-26] Comme Yar résume joliment ci-dessous, Avant de faire quoi que ce soit, assurez-vous de connaître l'URL du sous-module. Si inconnu, ouvrir .git/.gitmodules et examiner la clé submodule.<name>.url ._

Ce qui a marché pour moi, c'est de supprimer l'ancien sous-module en utilisant git submodule deinit <submodule> suivi par git rm <submodule-folder> . Puis ajoutez à nouveau le sous-module avec le nouveau nom de dossier et validez. La vérification du statut de git avant la validation montre que l'ancien sous-module a été renommé avec le nouveau nom et que le fichier .gitmodule a été modifié.

$ git submodule deinit foo
$ git rm foo
$ git submodule add https://bar.com/foo.git new-foo
$ git status
renamed:    foo -> new-foo
modified:   .gitmodules
$ git commit -am "rename foo submodule to new-foo"

1 votes

Cela nécessite git 1.8.3 ou plus. Voir ce post pour mettre à jour votre git : evgeny-goldin.com/blog/3-ways-install-git-linux-ubuntu

1 votes

Ou, une meilleure façon : sudo add-apt-repository ppa:git-core/ppa sudo apt-get update sudo apt-get install git

0 votes

@MichaelCole Merci ! Vous avez raison ! Voir Notes de mise à jour de Git-1.8.3 . FYI : Ubuntu-13.10 (Saucy Salamander) a Git-1.8.3.2 mais il est bon de savoir qu'il existe ppa . Aussi, IMHO Stratégie de fusion des sous-arbres git est une meilleure approche ; j'ai abandonné les submodules pour mes propres projets. Il est toujours bon de comprendre pour les projets existants.

13voto

Paul Gideon Dann Points 119

L'astuce semble être de comprendre que le .git pour les submodules sont maintenant conservés dans le dépôt maître, sous le nom de .git/modules et chaque sous-module a un .git qui pointe vers lui. C'est la procédure dont vous avez besoin maintenant :

  • Déplacez le sous-module vers son nouvel emplacement.
  • Modifier le .git dans le répertoire de travail du sous-module, et modifiez le chemin d'accès qu'il contient de manière à ce qu'il pointe vers le bon répertoire du référentiel maître. .git/modules répertoire.
  • Entrez le nom du référentiel maître .git/modules et trouvez le répertoire correspondant à votre sous-module.
  • Modifier le config en mettant à jour le fichier worktree afin qu'il pointe vers le nouvel emplacement du répertoire de travail du sous-module.
  • Modifier le .gitmodules dans le Root du référentiel maître, en mettant à jour le chemin vers le répertoire de travail du sous-module.
  • git add -u
  • git add <parent-of-new-submodule-directory> (Il est important d'ajouter le parent et non le répertoire du sous-module lui-même).

Quelques notes :

  • El [submodule "submodule-name"] lignes dans .gitmodules y .git/config doivent correspondre les uns aux autres, mais ne correspondent à rien d'autre.
  • Le répertoire de travail du sous-module et .git doivent pointer correctement l'un vers l'autre.
  • El .gitmodules y .git/config doivent être synchronisés.

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