Comment supprimer les fichiers répertoriés dans le .gitignore mais toujours dans le référentiel?

327

J'ai des fichiers dans mon référentiel qui doivent être ignorés, je les ai ajoutés au .gitignore mais, bien sûr, ils ne sont pas supprimés de mon référentiel.

Ma question est donc la suivante: existe-t-il une commande ou un script magique utilisant filter-branch qui peut réécrire mon historique et supprimer facilement tous ces fichiers? Ou simplement une commande qui créera un commit qui les supprimera?

Intrepidd
la source
AVERTISSEMENT: Bien que cela ne supprime pas le fichier physique de votre section locale, il supprimera les fichiers des autres machines des développeurs lors du prochain git pull. Comment faire pour que Git «oublie» un fichier qui a été suivi mais qui est maintenant dans .gitignore?
Kris Roofe
@Stevoisiak ce n'est pas un doublon de cette question car celui-ci pose des questions sur TOUS les fichiers ignorés et il a également une meilleure réponse que n'importe laquelle des questions similaires.
Omn

Réponses:

438

Vous pouvez les supprimer manuellement du référentiel:

git rm --cached file1 file2 dir/file3

Ou, si vous avez beaucoup de fichiers:

git rm --cached `git ls-files -i --exclude-from=.gitignore`

Mais cela ne semble pas fonctionner dans Git Bash sur Windows. Il produit un message d'erreur. Les éléments suivants fonctionnent mieux:

git ls-files -i --exclude-from=.gitignore | xargs git rm --cached  

En ce qui concerne la réécriture de toute l'histoire sans ces fichiers, je doute fortement qu'il existe un moyen automatique de le faire.
Et nous savons tous que réécrire l'histoire est mauvais, non? :)

Samy Dindane
la source
2
Malheureusement, la commande Git Bash sur Windows ne fonctionne pas avec les chemins qui contiennent des espaces
Nate Bundy
19
@Cupcake merci. git ls-files -i -z --exclude-from=.gitignore | xargs -0 git rm --cachedsemble faire l'affaire
Nate Bundy
3
Je suis resté coincé avec le même problème sur Windows. J'utilise PowerShell, et dans mon cas, j'ai reçu la troisième commande envoyée par @ samy-dindane et l'ai changé en foreach. C'est devenu çagit ls-files -i --exclude-from=.gitignore | %{git rm --cached $_}
digaomatias
1
"git ls-files -i --exclude-from = .gitignore" est très utile, il me dit quels fichiers sont exclus par .ignore.
Owen Cao
1
J'étais heureux de trouver ces commandes, MAIS cela ne supprime pas vraiment les fichiers du référentiel. Lorsque j'ai supprimé 2300 Ko d'images, la taille du référentiel n'a chuté que de 10 Ko. Il ne peut donc pas être utilisé, par exemple, pour rendre le référentiel plus petit et plus rapide à transférer.
Jan Potužník
343

Un moyen plus simple qui fonctionne sur n'importe quel OS est de faire

git rm -r --cached .
git add .
git commit -m "Removing all files in .gitignore"

Vous avez essentiellement lu tous les fichiers, sauf ceux du .gitignore

gtatr
la source
1
Comment cela affecte-t-il les autres utilisateurs sur le dépôt exécutant un pull - comme je l'ai lu, le dossier que nous ne voulons plus suivre est supprimé ??? Comment pouvons-nous empêcher cela - nous voulons simplement ne pas suivre
snh_nl
Cela marquera tous les fichiers comme modifiés avec un faux message de validation!
Haidar Zeineddine
3
qu'entendez-vous par un faux message de commit? C'est un vrai message de commit: P Vous pouvez bien sûr changer le message, selon vos besoins ...
gtatr
1
Par souci d'exhaustivité, vous avez besoin de la commande git push à la fin.
Mariusz Bialobrzeski
1
Ne faites pas cela, cela supprimera l'historique de tous les fichiers
agrath
145

Comme les fichiers en .gitignore ne sont pas suivis, vous pouvez utiliser la commande git clean pour supprimer récursivement les fichiers qui ne sont pas sous contrôle de version.

Utilisez git clean -xdnpour effectuer un essai à sec et voir ce qui sera retiré.
Utilisez ensuite git clean -xdfpour l'exécuter.

Fondamentalement, git clean -hou man git-clean(sous Unix) vous aidera.

N'oubliez pas que cette commande supprimera également les nouveaux fichiers qui ne se trouvent pas dans la zone de transfert.

J'espère que ça aide.

weiz
la source
6
Ce devrait être la réponse acceptée. Cela fonctionne réellement (la réponse acceptée ne fonctionnait pas pour moi, sur macOS), et c'est beaucoup plus propre.
Roger Oba
25
Cette réponse n'est pas applicable - le PO indique que les fichiers .gitignore sont en cours de suivi.
Ken Williams
20
IL FAUT SE MÉFIER! Cela supprime définitivement tous les fichiers non suivis, plutôt que de simplement supprimer de la branche
Emmanuel
1
la git clean -xdnest une marche à sec qui ne supprime pas. le prochain le fera.
JohnZaj
17
-1: Ceci est une réponse très trompeuse - l'affiche originale voulait supprimer du référentiel, pas supprimer complètement les fichiers. J'étais aussi près de supprimer une charge de fichiers dynamiques requis par mon IDE mais pas requis pour être dans le référentiel.
Auspice
4

J'ai fait une solution très simple en manipulant la sortie de l'instruction .gitignore avec sed:

cat .gitignore | sed '/^#.*/ d' | sed '/^\s*$/ d' | sed 's/^/git rm -r /' | bash

Explication:

  1. imprimer le fichier .gitignore
  2. supprimer tous les commentaires de l'impression
  3. supprimer toutes les lignes vides
  4. ajoutez 'git rm -r' au début de la ligne
  5. exécuter chaque ligne.
Scott Crossen
la source
10
sedest simple?
IgorGanapolsky
0

Sous linux, vous pouvez utiliser cette commande:

par exemple, je veux supprimer "* .py ~" donc ma commande devrait être ==>

find . -name "*.py~" -exec rm -f {} \;

Saloua SAHNOUNE
la source
-3

Le git ignorera les fichiers correspondant au modèle .gitignore après l'avoir ajouté à .gitignore.

Mais les fichiers qui existaient déjà dans le référentiel le seront toujours.

utiliser git rm files_ignored; git commit -m 'rm no use files'pour supprimer les fichiers ignorés.

pensz
la source
4
Il y en a beaucoup, existe-t-il un moyen de les supprimer sans avoir à préciser leur nom?
Intrepidd