J'aimerais changer le nom de répertoire d'un sous-module Git dans mon superprojet 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 d'abord (expliqué ici et ici ), puis en rajoutant il.
Git a-t-il vraiment besoin de l'intégralité du chemin dans la balise de sous-module?
[submodule ".emacs.d/vimpulse"]
ou est-il également possible de stocker uniquement le nom du sous-projet?
[submodule "vimpulse"]
Remarque: 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 de sous-modules:
Depuis git 1.8.5,
git mv old/submod new/submod
fonctionne comme prévu et effectue toute la plomberie pour vous. Vous voudrez peut-être utiliser git 1.9.3 ou plus récent, car il inclut des correctifs pour le déplacement de sous-modules.
Cela ressemble à la façon dont vous supprimez un sous-module (voir Comment puis-je supprimer un sous-module? ):
.gitmodules
et modifiez le chemin du sous-module en conséquence, puis insérez-le dans l'index avec git add .gitmodules
.mkdir -p new/parent
).mv -vi old/parent/submodule new/parent/submodule
).git add new/parent
).git rm --cached old/parent/submodule
..git/modules/old/parent/submodule
avec tout son contenu dans .git/modules/new/parent/submodule
..git/modules/new/parent/config
, assurez-vous que l'élément de la structure de travail pointe vers les nouveaux emplacements. Dans cet exemple, il devrait donc s'agir de worktree = ../../../../../new/parent/module
. En règle générale, il devrait y avoir deux autres répertoires ..
, puis dans le chemin direct à cet endroit.Editez le fichier new/parent/module/.git
, assurez-vous que son chemin pointe vers le nouvel emplacement correct dans le dossier du projet principal .git
. Dans cet exemple, gitdir: ../../../.git/modules/new/parent/submodule
.
git status
la 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
#
Enfin, validez les modifications.
La réponse la plus moderne, tirée du commentaire de Valloric ci-dessus:
git mv old/submod new/submod
git status
.)git commit
et vous voilà prêt à partir!Terminé!
Dans mon cas, je souhaitais déplacer un sous-module d’un répertoire vers un sous-répertoire, par exemple. "AFNetworking" -> "ext/AFNetworking". Ce sont les étapes que j'ai suivies:
[core] worktree
. Le mien est passé de ../../../AFNetworking
à ../../../../ext/AFNetworking
gitdir
. Le mien est passé de ../.git/modules/AFNetworking
à ../../git/modules/ext/AFNetworking
git add .gitmodules
git rm --cached AFNetworking
git submodule add -f <url> ext/AFNetworking
Enfin, j'ai vu dans le statut de 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 modifie pas la profondeur du répertoire, ce qui a une grande incidence sur la complexité de la tâche et sur 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 que se produirait si j’ajoutais un nouveau module sur ce chemin.)
[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 de le sous-module. Si inconnu, ouvrez .git/.gitmodules
et examinez la clé submodule.<name>.url
.
Ce qui a fonctionné pour moi a été de supprimer l'ancien sous-module en utilisant _git submodule deinit <submodule>
_ suivi de _git rm <submodule-folder>
_. Ajoutez ensuite le sous-module avec le nouveau nom de dossier et validez. Vérifier l'état de git avant de valider montre l'ancien sous-module renommé avec le nouveau nom et le .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"
_
L'astuce semble comprendre que le répertoire .git
des sous-modules est maintenant conservé dans le référentiel maître, sous .git/modules
, et que chaque sous-module comporte un fichier .git
qui le pointe. C'est la procédure dont vous avez besoin maintenant:
.git
dans le répertoire de travail du sous-module et modifiez le chemin qu'il contient pour qu'il pointe vers le répertoire de droite dans le répertoire .git/modules
du référentiel maître..git/modules
du référentiel maître et recherchez le répertoire correspondant à votre sous-module.config
en mettant à jour le chemin worktree
afin qu'il pointe vers le nouvel emplacement du répertoire de travail du sous-module..gitmodules
à la racine du référentiel maître, en mettant à jour le chemin d'accès au répertoire de travail du sous-module.git add -u
git add <parent-of-new-submodule-directory>
(Il est important que vous ajoutiez le parent, et non le répertoire du sous-module lui-même.)Quelques notes:
[submodule "submodule-name"]
dans .gitmodules
et .git/config
doivent être identiques, mais ne correspondent à rien d'autre..git
doivent se désigner correctement..gitmodules
et .git/config
doivent être synchronisés.Vous pouvez simplement ajouter un nouveau sous-module et supprimer l'ancien sous-module à l'aide de commandes standard. (devrait empêcher toute erreur accidentelle à l'intérieur de .git)
Exemple d'installation:
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>
Examinez le mouvement 'jquery' vers '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 bonus pour les grands sous-modules:
Si le sous-module est volumineux et que vous préférez ne pas attendre le clone, vous pouvez créer le nouveau sous-module en utilisant l'ancien en tant qu'origine, puis basculer l'origine.
Exemple (utilisez le même exemple d'installation)
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
...
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 effectuez la modification avant d'exécuter "git submodule init", cela fonctionnera correctement. Si vous apportez la modification (ou prenez la modification par une fusion), vous devrez soit modifier manuellement le fichier .git/config, soit exécuter à nouveau "git submodule init". Si vous faites cela, vous aurez une entrée inoffensive "échouée" avec l'ancien nom dans .git/config.
Je viens de traverser cette épreuve hier et cette réponse a parfaitement fonctionné. Voici mes étapes, pour plus de clarté:
more .gitmodules
car une fois que vous supprimez le sous-module, il ne sera plus disponible.deinit
, rm
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 le fait pas. Du tout.
Utilisez simplement le script shell git-submodule-move .
La solution proposée n'a pas fonctionné pour moi, cependant une version similaire a fonctionné ...
Il s’agit d’un référentiel cloné; par conséquent, les dépôts git du sous-module sont contenus dans les référentiels supérieurs .git dir. Tous les cations proviennent du référentiel supérieur:
Modifiez .gitmodules et modifiez le paramètre "path =" pour le sous-module en question. (Pas besoin de changer l'étiquette, ni d'ajouter ce fichier à l'index.)
Editez .git/modules/name/config et modifiez le paramètre "worktree =" pour le sous-module en question
courir:
mv submodule newpath/submodule
git add -u
git add newpath/submodule
Je me demande si cela fait une différence si les référentiels sont atomiques, ou des sous-modules relatifs, dans mon cas, il était relatif (submodule/.git est une référence pour renvoyer à topproject/.git/modules/submodule)