Comment puis-je retirer un sous-module Git?
À propos, y a-t-il une raison pour laquelle je ne peux pas simplement faire git submodule rm whatever
?
Depuis git1.8.3 (22 avril 2013) :
Il n’existait aucun moyen en porcelaine de dire "je ne suis plus intéressé par ce sous-module", une fois que vous avez exprimé votre intérêt pour un sous-module avec "_
submodule init
_".
"submodule deinit
" est le moyen de le faire.
Le processus de suppression utilise également _git rm
_ (depuis git1.8.5 octobre 2013).
Le processus de suppression en 3 étapes serait alors:
_0. mv a/submodule a/submodule_tmp
1. git submodule deinit -f -- a/submodule
2. rm -rf .git/modules/a/submodule
3. git rm -f a/submodule
# Note: a/submodule (no trailing slash)
# or, if you want to leave it in your working tree and have done step 0
3. git rm --cached a/submodule
3bis mv a/submodule_tmp a/submodule
_
_rm -rf
_: Ceci est mentionné dans Daniel Schroederréponse , et résumé par Eonil dans les commentaires =:
Cela laisse _
.git/modules/<path-to-submodule>/
_ inchangé.
Donc, si vous supprimez une fois un sous-module avec cette méthode et que vous le rajoutez à nouveau, cela ne sera pas possible car le référentiel a déjà été corrompu.
_git rm
_: Voir commit 95c16418 :
L'utilisation actuelle de "_
git rm
_" sur un sous-module supprime l'arbre de travail du sous-module de celui du superprojet et le lien gitlink de l'index.
Mais la section du sous-module dans _.gitmodules
_ est laissée intacte, ce qui est un reste du sous-module supprimé et pourrait irriter les utilisateurs (par opposition à la configuration dans _.git/config
_, elle doit rester comme suit: rappel que l’utilisateur a manifesté de l’intérêt pour ce sous-module afin qu’il soit repeuplé plus tard lorsqu’une ancienne validation est extraite).Laissez "_
git rm
_" aider l'utilisateur en supprimant non seulement le sous-module de l'arbre de travail, mais également en supprimant la section "_submodule.<submodule name>
_" du fichier _.gitmodules
_ et en exécutant les deux.
_git submodule deinit
_: Cela provient de ce correctif :
Avec "_
git submodule init
_", l'utilisateur est en mesure d'indiquer à son ami qu'il se soucie d'un ou de plusieurs sous-modules et qu'il souhaite le renseigner lors du prochain appel à "_git submodule update
_".
Mais il n’existe actuellement aucun moyen simple de dire à git qu’ils ne se soucient plus du sous-module et qu’ils veulent supprimer l’arborescence de travail locale (à moins que l’utilisateur connaisse beaucoup de choses sur les éléments internes du sous-module et supprime le "_submodule.$name.url
_ "à partir de _.git/config
_ avec l'arbre de travail lui-même).Aidez ces utilisateurs en fournissant une commande '
deinit
'.
Ceci supprime la section entière _submodule.<name>
_ de _.git/config
_ soit pour le ou les sous-modules donnés (ou pour tous ceux qui ont été initialisés si '_.
_' est donné).
Échec si l’arbre de travail actuel contient des modifications, à moins qu’il soit forcé.
Indiquez si, pour un sous-module indiqué sur la ligne de commande, le paramètre d'URL est introuvable dans _.git/config
_, mais n'échouez pas pour autant.
Ceci est utile si les étapes de (dé) initialisation (_.git/config
_ et _.git/modules/xxx
_)
Depuis git1.8.5, le _git rm
_ prend également en charge de la:
add
' qui enregistre l'URL d'un sous-module dans le fichier _.gitmodules
_: il doit être supprimé pour vous.git rm --cached path_to_submodule
_ (sans barre oblique)Si vous oubliez cette dernière étape et essayez d'ajouter ce qui était un sous-module à un répertoire normal, vous obtiendrez un message d'erreur du type:
_git add mysubmodule/file.txt
Path 'mysubmodule/file.txt' is in submodule 'mysubmodule'
_
Remarque: depuis Git 2.17 (T2 2018), le sous-module git deinit n'est plus un script Shell.
C'est un appel à une fonction C.
Voir commit 2e6127 , commit 1342476 (14 janvier 2018) par Prathamesh Chavan (_pratham-pc
_) .
(Fusion par Junio C Hamano - gitster
- dans commit ead8dbe , 13 février 2018)
_git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit \
${GIT_QUIET:+--quiet} \
${prefix:+--prefix "$prefix"} \
${force:+--force} \
${deinit_all:+--all} "$@"
_
Via la page Tutoriel Git Submodule:
Pour supprimer un sous-module, vous devez:
.gitmodules
..gitmodules
:git add .gitmodules
.git/config
.git rm --cached path_to_submodule
(pas de barre oblique)..git
du sous-module:rm -rf .git/modules/path_to_submodule
git commit -m "Removed submodule <name>"
rm -rf path_to_submodule
Voir aussi : étapes alternatives ci-dessous .
Juste une note. Depuis git 1.8.5.2, deux commandes suffiront:
git rm the_submodule
rm -rf .git/modules/the_submodule
Comme le soulignait correctement la réponse de @Mark Cheverton, si la deuxième ligne n'est pas utilisée, même si vous supprimez le sous-module pour l'instant, le dossier restant .git/modules/the_submodule empêchera l'ajout ou le remplacement ultérieur du même sous-module. . De plus, comme @VonC l'a mentionné, git rm
effectuera l'essentiel du travail sur un sous-module.
--Mise à jour (07/05/2017) -
Juste pour clarifier, the_submodule
est le chemin relatif du sous-module à l'intérieur du projet. Par exemple, il s'agit de subdir/my_submodule
si le sous-module se trouve dans un sous-répertoire subdir
.
Comme indiqué correctement dans les commentaires et autres réponses , les deux commandes (bien que leur fonctionnement soit suffisant pour supprimer un sous-module), laissent une trace dans la section [submodule "the_submodule"]
de .git/config
( à partir de juillet 2017), qui peuvent être supprimés à l'aide d'une troisième commande:
git config -f .git/config --remove-section submodule.the_submodule 2> /dev/null
La majorité des réponses à cette question sont obsolètes, incomplètes ou inutilement complexes.
Un sous-module cloné avec git 1.7.8 ou plus récent laissera au maximum quatre traces de lui-même dans votre dépôt local. Le processus de suppression de ces quatre traces est donné par les trois commandes ci-dessous:
# Remove the submodule entry from .git/config
git submodule deinit -f path/to/submodule
# Remove the submodule directory from the superproject's .git/modules directory
rm -rf .git/modules/path/to/submodule
# Remove the entry in .gitmodules and remove the submodule directory located at path/to/submodule
git rm -f path/to/submodule
Étapes simples
git config -f .git/config --remove-section submodule.$submodulename
git config -f .gitmodules --remove-section submodule.$submodulename
git rm --cached $submodulepath
rm -rf $submodulepath
rm -rf .git/modules/$submodulename
Remarque: $submodulepath
ne contient pas de barre oblique ni de fin.
Arrière-plan
Quand vous faites git submodule add
, il ne fait que l'ajouter à .gitmodules
, mais une fois que vous avez fait git submodule init
, il a été ajouté à .git/config
.
Donc, si vous souhaitez supprimer les modules, mais pouvoir le restaurer rapidement, procédez comme suit:
git rm --cached $submodulepath
git config -f .git/config --remove-section submodule.$submodulepath
C'est une bonne idée de faire git rebase HEAD
en premier et git commit
à la fin, si vous mettez cela dans un script.
Regardez aussi ne réponse à Puis-je dépeupler un sous-module Git? .
En plus des recommandations, je devais aussi rm -Rf .git/modules/path/to/submodule
pour pouvoir ajouter un nouveau sous-module du même nom (dans mon cas, je remplaçais une fourche par l'original).
Pour supprimer un sous-module ajouté en utilisant:
git submodule add [email protected]:repos/blah.git lib/blah
Courir:
git rm lib/blah
C'est ça.
Pour les anciennes versions de git (environ 1.8.5), utilisez:
git submodule deinit lib/blah
git rm lib/blah
git config -f .gitmodules --remove-section submodule.lib/blah
Vous devez supprimer l'entrée dans .gitmodules
et .git/config
, et supprimer le répertoire du module de l'historique:
git rm --cached path/to/submodule
Si vous écrivez sur la liste de diffusion de git, il est probable que quelqu'un fera un script Shell pour vous.
Vous pouvez utiliser un alias pour automatiser les solutions fournies par d'autres:
[alias]
rms = "!f(){ git rm --cached \"$1\";rm -r \"$1\";git config -f .gitmodules --remove-section \"submodule.$1\";git config -f .git/config --remove-section \"submodule.$1\";git add .gitmodules; }; f"
Mettez cela dans votre configuration git, et ensuite vous pourrez faire: git rms path/to/submodule
Pour résumer, voici ce que vous devriez faire:
Définissez path_to_submodule
var (pas de barre oblique):
path_to_submodule=path/to/submodule
Supprimez la ligne correspondante du fichier .gitmodules:
git config -f .gitmodules --remove-section submodule.$path_to_submodule
Supprimer la section correspondante de .git/config
git config -f .git/config --remove-section submodule.$path_to_submodule
Décompressez et supprimez $ path_to_submodule uniquement de l'index (pour éviter de perdre des informations)
git rm --cached $path_to_submodule
Suivre les modifications apportées aux .gitmodules
git add .gitmodules
Commettre le superprojet
git commit -m "Remove submodule submodule_name"
Supprimer les fichiers de sous-module maintenant non suivis
rm -rf $path_to_submodule
rm -rf .git/modules/$path_to_submodule
Si le sous-module a été ajouté accidentellement parce que vous avez ajouté, validé et envoyé un dossier qui était déjà un référentiel Git (contenant .git
), vous avez gagné. Vous n'avez pas de fichier .gitmodules
à modifier, ni rien dans .git/config
. Dans ce cas, tout ce dont vous avez besoin c'est:
git rm --cached subfolder
git add subfolder
git commit -m "Enter message here"
git Push
FWIW , j'ai également supprimé le dossier .git
avant de faire le git add
.
J'ai trouvé que deinit
fonctionnait bien pour moi:
git submodule deinit <submodule-name>
git rm <submodule-name>
De git docs :
deinit
Annulez l'enregistrement des sous-modules donnés, c'est-à-dire supprimez toute la section
submodule.$name
de .git/config ainsi que leur arbre de travail.
Après avoir essayé toutes les réponses sur ce site, je me suis retrouvé avec cette solution:
#!/bin/sh
path="$1"
if [ ! -f "$path/.git" ]; then
echo "$path is no valid git submodule"
exit 1
fi
git submodule deinit -f $path &&
git rm --cached $path &&
rm -rf .git/modules/$path &&
rm -rf $path &&
git reset HEAD .gitmodules &&
git config -f .gitmodules --remove-section submodule.$path
Cela restaure exactement le même état qu'avant l'ajout du sous-module. Vous pouvez immédiatement rajouter le sous-module, ce qui n’était pas possible avec la plupart des réponses fournies ici.
git submodule add $giturl test
aboveScript test
Cela vous laisse avec une nouvelle commande sans modifications à valider.
Ceci a été testé avec:
$ git --version
git version 1.9.3 (Apple Git-50)
Ce que je fais actuellement en décembre 2012 (combine la plupart de ces réponses):
oldPath="vendor/example"
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 src (optional)
rm -rf ".git/modules/${oldPath}" ## cleanup gitdir (optional Housekeeping)
git add .gitmodules
git commit -m "Removed ${oldPath}"
Voici ce que j'ai fait :
1.) Supprimez la section correspondante du fichier .gitmodules. Vous pouvez utiliser la commande ci-dessous:
git config -f .gitmodules --remove-section "submodule.submodule_name"
2.) Mettez en scène les modifications .gitmodules
git add .gitmodules
3.) Supprimez la section correspondante de .git/config
. Vous pouvez utiliser la commande ci-dessous:
git submodule deinit -f "submodule_name"
4.) Supprimer le gitlink (pas de barre oblique):
git rm --cached path_to_submodule
5.) Nettoyer le .git/modules
:
rm -rf .git/modules/path_to_submodule
6.) S'engager:
git commit -m "Removed submodule <name>"
7.) Supprimer les fichiers de sous-module maintenant non suivis
rm -rf path_to_submodule
Je découvre récemment un projet git qui inclut de nombreuses commandes utiles liées à git: https://github.com/visionmedia/git-extras
Installez-le et tapez:
git-delete-submodule submodule
Alors les choses sont faites. Le répertoire du sous-module sera supprimé de votre référentiel et existe toujours dans votre système de fichiers. Vous pouvez ensuite valider le changement comme suit: git commit -am "Remove the submodule"
.
Je devais aller un peu plus loin dans les étapes de John Douthat et cd
dans le répertoire du sous-module, puis supprimer le référentiel Git:
cd submodule
rm -fr .git
Ensuite, je pourrais valider les fichiers dans le référentiel Git parent sans l'ancienne référence à un sous-module.
Voici les 4 étapes que j'ai trouvées nécessaires ou utiles (les plus importantes en premier):
git rm -f the_submodule
rm -rf .git/modules/the_submodule
git config -f .git/config --remove-section submodule.the_submodule
git commit -m "..."
En théorie , git rm
à , l'étape 1 devrait prendre soin de de cela. Espérons que la deuxième partie de la question OP puisse recevoir une réponse positive un jour (que cela puisse être fait en une seule commande).
Mais à partir de juillet 2017, l'étape 2 est nécessaire pour supprimer les données de .git/modules/
, sinon vous ne pouvez pas, par exemple. ajoutez le sous-module dans le futur.
Vous pouvez probablement vous passer des deux étapes précédentes pour git 1.8.5+ comme réponse de tinlyx , car toutes les commandes git submodule
semblent fonctionner.
L'étape 3 supprime la section pour the_submodule
dans le fichier .git/config
. Cela devrait être fait pour être complet. (L'entrée peut causer des problèmes pour les anciennes versions de git, mais je n'en ai pas à tester).
Pour cela, la plupart des réponses suggèrent d'utiliser git submodule deinit
. Je trouve plus explicite et moins déroutant d'utiliser git config -f .git/config --remove-section
. Selon le documentation de git-submodule , git deinit
:
Désenregistrer les sous-modules donnés ... Si vous voulez vraiment supprimer un sous-module du référentiel et commettez-le, utilisez plutôt git-rm [1] .
Dernier point mais non le moindre, si vous n'avez pas git commit
, vous obtiendrez une erreur en faisant git submodule summary
(à partir de git 2.7):
fatal: Not a git repository: 'the_submodule/.git'
* the_submodule 73f0d1d...0000000:
Ceci indépendamment du fait que vous fassiez les étapes 2 ou 3.
project dir: ~/foo_project/
submodule: ~/foo_project/lib/asubmodule
- - - - - - - - - - - - - - - - - - - - - - - - -
run:
1. cd ~/foo_project
2. git rm lib/asubmodule &&
rm .git/modules/lib/asubmodule &&
git submodule lib/asubmodule deinit --recursive --force
Je viens de trouver le fichier caché du sous-module (nom exact oublié). Il contient une liste ... vous pouvez les effacer individuellement de cette façon. Je viens d'en avoir un, je l'ai donc supprimé. C'est simple, mais ça risque de gâcher Git, car je ne sais pas si quelque chose est attaché au sous-module. Cela semble correct jusqu'à présent, mis à part le problème de mise à niveau habituel de libetpan, mais ce n'est (espérons-le) pas lié.
Remarqué personne n'a posté d'effacement manuel, donc ajouté
Si vous venez d'ajouter le sous-module, et par exemple si vous avez simplement ajouté le mauvais sous-module ou si vous l'avez ajouté au mauvais endroit, il vous suffit de faire git stash
puis de supprimer le dossier. Ceci suppose que l'ajout du sous-module est la seule chose que vous avez faite dans le repo récent.
Avec Git 2.17 et supérieur, c'est juste:
git submodule deinit -f {module_name}
git add {module_name}
git commit
J'ai créé un script bash pour faciliter le processus de suppression. Il vérifie également s'il y a des modifications dans le référentiel non enregistrées et demande une confirmation. Il a été testé sur os x
il serait intéressant de savoir s'il fonctionne tel quel sur les distributions linux courantes:
https://Gist.github.com/fabifrank/cdc7e67fd194333760b060835ac0172f
Dans la dernière version de git, il suffit de 4 opérations pour retirer le sous-module git.
.gitmodules
git add .gitmodules
git rm --cached <path_to_submodule>
git commit -m "Removed submodule xxx"