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

j'aimerais changer le nom du répertoire d'un sous-module Git dans mon superproject git.

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

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

Qu'est-ce que je dois taper pour déplacer le répertoire .emacs.d/vimpulse vers .emacs.d/vendor/vimpulse sans le supprimer en premier (expliqué ici et ici ) et puis de rajouter.

Ne Git vraiment besoin de l' chemin complet dans le sous-module tag

[submodule ".emacs.d/vimpulse"]

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

[submodule "vimpulse"]
282
demandé sur Community 2011-01-05 16:24:29

10 réponses

Note: tel que mentionné dans les commentaires cette réponse fait référence aux étapes nécessaires avec les versions plus anciennes de git. Git a maintenant le support natif pour déplacer des sous-modules:

Depuis git 1.8.5, git mv old/submod new/submod fonctionne comme prévu et la plomberie pour vous. Vous pourriez vouloir utiliser git 1.9.3 ou plus récent, parce qu'il comprend des correctifs pour le déplacement de submodule.


c'est similaire à comment vous retirez un sous-module (voir Comment puis-je enlever un sous-module? ):

  1. modifier .gitmodules et changer le chemin du sous-module de manière appropriée, et le mettre dans l'index avec git add .gitmodules .
  2. si nécessaire, créer le répertoire parent du nouvel emplacement du sous-module ( mkdir -p new/parent ).
  3. Déplacer tout le contenu de l'ancien vers le nouveau répertoire ( mv -vi old/parent/submodule new/parent/submodule ).
  4. assurez-vous que Git trace ce répertoire ( git add new/parent ).
  5. Supprimer 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. éditez le fichier .git/modules/new/parent/config , assurez-vous que l'item worktree 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 .. puis des répertoires dans le chemin direct lieu.
  8. éditez le fichier new/parent/module/.git , assurez-vous que le chemin dans celui-ci Pointe à la nouvelle localisation correcte à l'intérieur du projet principal .git dossier, donc dans cet exemple gitdir: ../../../.git/modules/new/parent/submodule .

    git status sortie ressemble à ceci pour moi par la suite:

    # 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, commit the changes.

266
répondu Axel Beckert 2017-09-21 16:34:35

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

  1. la Mise à niveau vers Git 2.0 (ou au moins 1.9.3)
  2. git mv old/submod new/submod
  3. après le .gitmodules et le répertoire submodule sont déjà mis en scène pour un commit (vous pouvez le vérifier avec git status ).)
  4. valider les modifications avec git commit et vous êtes bon pour aller!

fait!

182
répondu phatmann 2015-05-07 13:36:46

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

  1. Edit .gitmodules changement de sous-module nom et le chemin pour être "ext/AFNetworking"
  2. Déplacer les sous-module git du répertoire à partir de ".git/modules/AFNetworking" pour ".git / modules / ext / AFNetworking "
  3. déplacer la bibliothèque de "AFNetworking" à "ext / AFNetworking""
  4. Modifier ".git/modules/ext/AFNetworking / config" et fixer la ligne [core] worktree . Mine changée de ../../../AFNetworking à ../../../../ext/AFNetworking
  5. Modifier "ext/AFNetworking/.git "et fix gitdir . Mine changée de ../.git/modules/AFNetworking à ../../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 le tour est joué. L'exemple ci-dessus ne change pas la profondeur du répertoire, ce qui fait une grande différence à la complexité de la tâche, et ne change pas le nom du sous-module (qui peut ne pas être vraiment nécessaire, mais je l'ai fait pour être cohérent avec ce qui se produirait si j'ajoutais un nouveau module à ce chemin.)

54
répondu Matt Connolly 2012-04-28 12:22:30

[mise à jour: 2014-11-26] comme Yar résume bien ci-dessous, avant de faire quoi que ce soit, assurez-vous de connaître l'URL du sous-module. si Inconnu, ouvrez .git/.gitmodules et examinez la clé submodule.<name>.url .

ce qui a fonctionné pour moi était de enlever le vieux sous-module en utilisant git submodule deinit <submodule> suivi de git rm <submodule-folder> . Puis Ajouter le sous-module avec le nouveau nom de dossier et commit. Vérifier l'état de git avant de commettre montre l'ancien sous-module renommé au nouveau nom et .gitmodule 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"
16
répondu Mark Mikofski 2017-05-23 10:31:31

le truc semble être de comprendre que le répertoire .git pour les sous-modules sont maintenant conservés dans le dépôt principal, sous .git/modules , et chaque sous-module a un fichier .git qui le pointe. C'est la procédure dont vous avez besoin maintenant:

  • déplacer le sous-module à sa nouvelle maison.
  • éditer le fichier .git dans le répertoire de travail du sous-module, et modifier le chemin qu'il contient pour qu'il pointe vers la droite répertoire dans le répertoire .git/modules du dépôt principal.
  • entrez dans le répertoire .git/modules du dépôt principal et trouvez le répertoire correspondant à votre sous-module.
  • éditez le fichier config , en mettant à jour le chemin worktree pour qu'il pointe vers le nouvel emplacement du répertoire de travail du sous-module.
  • édite le fichier .gitmodules dans la racine du dépôt principal, mettant à jour le chemin vers le répertoire 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 submodule lui-même.)

quelques notes:

  • les lignes [submodule "submodule-name"] dans .gitmodules et .git/config doivent correspondre les unes aux autres, mais ne correspondent à rien d'autre.
  • le fonctionnement du sous-module répertoire et répertoire .git doivent pointer correctement l'un vers l'autre.
  • les fichiers .gitmodules et .git/config doivent être synchronisés.
11
répondu Paul Gideon Dann 2012-11-14 13:16:32

vous pouvez simplement ajouter un nouveau sous-module et supprimer l'ancien sous-module en utilisant des commandes standard. (devrait prévenir toute erreur accidentelle à l'intérieur de .git)

exemple de configuration:

mkdir foo; cd foo; git init; 
echo "readme" > README.md; git add README.md; git commit -m "First"
## add submodule
git submodule add git://github.com/jquery/jquery.git
git commit -m "Added jquery"
## </setup example>

exemple move" jquery " to "vendor/jquery / jquery":

oldPath="jquery"
newPath="vendor/jquery/jquery"
orginUrl=`git config --local --get submodule.${oldPath}.url`

## add new submodule
mkdir -p `dirname "${newPath}"`
git submodule add -- "${orginUrl}" "${newPath}"

## remove old submodule
git config -f .git/config --remove-section "submodule.${oldPath}"
git config -f .gitmodules --remove-section "submodule.${oldPath}"
git rm --cached "${oldPath}"
rm -rf "${oldPath}"              ## remove old src
rm -rf ".git/modules/${oldPath}" ## cleanup gitdir (housekeeping)

## commit
git add .gitmodules
git commit -m "Renamed ${oldPath} to ${newPath}"

méthode de Bonus pour les sous-modules de grande taille:

si le sous-module est grand et que vous préférez ne pas attendre le clone, vous pouvez créer le nouveau sous-module en utilisant l'ancien comme origine, puis changer l'origine.

exemple (utilisez le même exemple de configuration)

oldPath="jquery"
newPath="vendor/jquery/jquery"
baseDir=`pwd`
orginUrl=`git config --local --get submodule.${oldPath}.url`

# add new submodule using old submodule as origin
mkdir -p `dirname "${newPath}"`
git submodule add -- "file://${baseDir}/${oldPath}" "${newPath}"

## change origin back to original
git config -f .gitmodules submodule."${newPath}".url "${orginUrl}"
git submodule sync -- "${newPath}"

## remove old submodule
...
9
répondu Lance Rushing 2012-12-18 23:06:35

la chaîne entre guillemets après "[submodule " n'a pas d'importance. Vous pouvez le changer en" foobar " si vous voulez. Il est utilisé pour trouver l'entrée correspondante dans ".git / config".

par conséquent, si vous faites le changement avant d'exécuter "git sous-module init", ça marchera très bien. Si vous effectuez la modification (ou si vous la récupérez par une fusion), vous devrez éditer manuellement .git/config ou exécuter "git sous-module init" à nouveau. Si vous faites ce dernier, vous serez laissé avec un inoffensif "échoué" entrée avec l'ancien nom .git / config.

8
répondu Bob Bell 2011-01-05 17:47:02

la solution donnée n'a pas fonctionné pour moi, cependant une version similaire l'a fait...

c'est avec un dépôt cloné, donc les repos git submodule sont contenus dans les dépôts supérieurs .git dir. Tous les cations proviennent du dépôt supérieur:

  1. Éditer .gitmodules et changer le paramètre" path = " pour le sous-module en question. (Pas besoin de changer de label, ni d'ajouter ce fichier à l'index.)

  2. Edit .git/modules/nom/config et modifier la "worktree =" paramètre du sous-module en question

  3. run:

    mv submodule newpath/submodule
    git add -u
    git add newpath/submodule
    

je me demande si cela fait une différence si les dépôts sont atomiques, ou des sous-modules relatifs, dans mon cas c'était relatif (sous-module/.git est une référence de retour à topproject/.git/modules/sous-module)

2
répondu arand 2012-04-25 20:00:04

il suffit d'utiliser le script shell git-sous-module-déplacer .

2
répondu Flimm 2013-07-22 12:20:31

je viens de traverser cette épreuve hier et cette réponse a fonctionné parfaitement. Voici mes étapes, pour plus de clarté:

  1. S'assurer que le sous-module est enregistré et poussé sur son serveur. Vous devez aussi savoir sur quelle branche il est.
  2. vous avez besoin de L'URL de votre sous-module! utilisez more .gitmodules car une fois que vous supprimez le sous-module, il ne sera pas autour
  3. Maintenant vous pouvez utiliser deinit , rm et puis submodule add

exemple

commandes

    git submodule deinit Classes/lib/mustIReally
    git rm foo
    git submodule add http://developer.audiob.us/download/SDK.git lib/AudioBus

    # do your normal commit and push
    git commit -a 

NOTE: git mv ne fait pas cela. À tous.

1
répondu Dan Rosenstark 2017-05-23 12:03:03