Supprimer le répertoire du référentiel distant après l'avoir ajouté à .gitignore

599

J'ai commis et poussé un répertoire vers github. Après cela, j'ai modifié le .gitignorefichier en ajoutant un répertoire qui devrait être ignoré. Tout fonctionne bien, mais le répertoire (désormais ignoré) reste sur github.

Comment supprimer ce répertoire de github et de l'historique du référentiel?

janw
la source
2
Dupliquer des fichiers

Réponses:

1067

Les règles de votre .gitignorefichier s'appliquent uniquement aux fichiers non suivis. Étant donné que les fichiers de ce répertoire ont déjà été validés dans votre référentiel, vous devez les décompresser, créer un commit et le pousser vers GitHub:

git rm -r --cached some-directory
git commit -m 'Remove the now ignored directory "some-directory"'
git push origin master

Vous ne pouvez pas supprimer le fichier de votre historique sans réécrire l'historique de votre référentiel - vous ne devriez pas le faire si quelqu'un d'autre travaille avec votre référentiel, ou si vous l'utilisez à partir de plusieurs ordinateurs. Si vous voulez toujours le faire, vous pouvez utiliser git filter-branchpour réécrire l'historique - il y a un guide utile ici .

De plus, notez que la sortie de git rm -r --cached some-directorysera quelque chose comme:

rm 'some-directory/product/cache/1/small_image/130x130/small_image.jpg'
rm 'some-directory/product/cache/1/small_image/135x/small_image.jpg'
rm 'some-directory/.htaccess'
rm 'some-directory/logo.jpg'

Il rms'agit des commentaires de git sur le référentiel; les fichiers sont toujours dans le répertoire de travail.

Mark Longair
la source
3
Si quelqu'un d'autre tire, les fichiers désormais ignorés seront-ils supprimés pour eux ou resteront-ils intacts?
Martin Konicek
3
@Martin Konicek: si l'utilisateur qui tire ces modifications n'a aucune modification de ces fichiers, ils seront supprimés.
Mark Longair
@MarkLongair Que fait -ret --cached. Merci.
Labanino
13
@Labanino: -rsignifie récursif, nécessaire si vous faites des répertoires entiers. --cachedremplace le comportement normal de git de les supprimer du répertoire de travail et de planifier la suppression pour la validation, et fait que git ne fonctionne que sur la zone de préparation prête à la validation. C'est ainsi que vous dites à git que vous souhaitez conserver vos copies locales des fichiers.
2015 à 18h16
2
Cela fonctionne bien, mais je devais d'abord le faire: git reset name_of_filepour que ce qui est décrit ci-dessus fonctionne
Edvard Haugland
248

Je fais ça:

git rm --cached `git ls-files -i --exclude-from=.gitignore` 
git commit -m 'Removed all files that are in the .gitignore' 
git push origin master

Ce qui supprimera tous les fichiers / dossiers qui sont dans votre git ignorer, vous devez donc les sélectionner manuellement


Cela semble avoir cessé de fonctionner pour moi, je fais maintenant:

 git rm -r --cached . 
 git add .
 git commit -m 'Removed all files that are in the .gitignore' 
 git push origin master
Blundell
la source
4
Merci, cela m'a beaucoup aidé! Si vous utilisez Windows PowerShell, vous pouvez le faireforeach ($i in iex 'git ls-files -i --exclude-from=.gitignore') { git rm --cached $i }
Matthew
10
J'ai essayé votre deuxième approche, elle a supprimé tous les fichiers de mon git local!
artnikpro
2
Je pense que vous êtes censé naviguer vers le sous-répertoire et le faire. Corrige moi si je me trompe.
Alors qu'avons-nous appris aujourd'hui, les enfants? "Ne lancez pas de code aléatoire que vous trouvez sur Stack Overflow!"
Jonathan Landrum
49

Selon ma réponse ici: Comment supprimer un répertoire du référentiel git?

Pour supprimer le dossier / répertoire uniquement du référentiel git et non du local, essayez 3 étapes simples.


Étapes pour supprimer le répertoire

git rm -r --cached FolderName
git commit -m "Removed folder from repository"
git push origin master

Étapes pour ignorer ce dossier dans les prochains validations

Pour ignorer ce dossier à partir des validations suivantes, créez un fichier à la racine nommé .gitignore et mettez-y le nom de ce dossier. Vous pouvez en mettre autant que vous le souhaitez

Le fichier .gitignore ressemblera à ceci

/FolderName

supprimer le répertoire

eirenaios
la source
1
Ceci est exactement ce que je cherchais. Merci :)
Rohit Singh
Je suis heureux que cela ait aidé @Rohit Singh
eirenaios
9

La première réponse de Blundell n'a pas fonctionné pour moi. Mais cela m'a montré le bon chemin. J'ai fait la même chose comme ça:

> for i in `git ls-files -i --exclude-from=.gitignore`; do git rm --cached $i; done
> git commit -m 'Removed all files that are in the .gitignore'
> git push origin master

Je vous conseille de vérifier d'abord les fichiers à supprimer en exécutant l'instruction ci-dessous:

git ls-files -i --exclude-from=.gitignore

J'utilisais un fichier .gitignore par défaut pour Visual Studio et j'ai remarqué qu'il supprimait tous les journaux et les dossiers bin du projet, ce qui n'était pas mon action prévue.

Oncel Umut TURER
la source
5

Remarque: Cette solution fonctionne uniquement avec l' interface graphique Github Desktop .

En utilisant l' interface graphique de Github Desktop, c'est très simple.

  1. Déplacez le dossier vers un autre emplacement (pour sortir du dossier du projet) temporairement.

  2. Modifiez votre .gitignorefichier et supprimez l'entrée du dossier qui serait supprimer le référentiel maître sur la page github.

  3. Validez et synchronisez le dossier du projet.

  4. Déplacer le dossier dans le dossier du projet

  5. Rééditez le .gitignorefichier.

C'est tout.

efkan
la source
5

La réponse de Blundell devrait fonctionner, mais pour une raison bizarre, cela ne me concerne pas. J'ai dû d'abord canaliser les noms de fichiers générés par la première commande dans un fichier, puis parcourir ce fichier et supprimer ce fichier un par un.

git ls-files -i --exclude-from=.gitignore > to_remove.txt
while read line; do `git rm -r --cached "$line"`; done < to_remove.txt
rm to_remove.txt
git commit -m 'Removed all files that are in the .gitignore' 
git push origin master
Chris Aelbrecht
la source
4

Cette méthode applique le comportement .gitignore standard et ne nécessite pas de spécifier manuellement les fichiers à ignorer .

Je ne peux plus utiliser --exclude-from=.gitignore: / - Voici la méthode mise à jour:

Conseil général: commencez par un dépôt propre - tout est validé, rien en attente dans le répertoire de travail ou l'index, et faites une sauvegarde !

#commit up-to-date .gitignore (if not already existing)
#this command must be run on each branch
git add .gitignore
git commit -m "Create .gitignore"

#apply standard git ignore behavior only to current index, not working directory (--cached)
#if this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist
#this command must be run on each branch
git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached

#optionally add anything to the index that was previously ignored but now shouldn't be:
git add *

#commit again
#optionally use the --amend flag to merge this commit with the previous one instead of creating 2 commits.

git commit -m "re-applied modified .gitignore"

#other devs who pull after this commit is pushed will see the  newly-.gitignored files DELETED

Si vous devez également purger les fichiers nouvellement ignorés de l'historique de validation de la branche ou si vous ne souhaitez pas que les fichiers nouvellement ignorés soient supprimés des futurs pulls , consultez cette réponse .

goofologie
la source
0

Si vous travaillez à partir de PowerShell, essayez ce qui suit en tant que commande unique.

PS MyRepo> git filter-branch --force --index-filter
>> "git rm --cached --ignore-unmatch -r .\\\path\\\to\\\directory"
>> --prune-empty --tag-name-filter cat -- --all

Ensuite, git push --force --all.

Documentation: https://git-scm.com/docs/git-filter-branch

Shaun Luttin
la source
En quoi l'utilisation est-elle git filter-branchdifférente de l'utilisation git rm? Je pensais à l'origine que je devais utiliser une version de git filter-branchmais la plupart des commentaires ici recommandent de l'utiliser git rm. D'après ce que je comprends, git rmne le supprime que du répertoire de travail et de l'index en cours. Mais si ses multiples validations ajoutées auparavant, il sera toujours dans le référentiel.
alpha_989
Droite. git rmsupprimera le fichier de la dernière validation à l'avenir. git filter-branchnous permet de le supprimer de toute l'histoire. Voir aussi: help.github.com/articles/…
Shaun Luttin