git rm - fatal: pathspec ne correspond à aucun fichier

87

J'ai ajouté plus de 9000 photos par accident à mon dossier de projet. Et les a commis. Ensuite, supprimez-les du disque. Engagé.

Maintenant, j'essaye de pousser les modifications vers le serveur git. Mais cela prend trop de temps et essaie d'envoyer 12 Go de données.

J'ai vérifié la taille des fichiers sur le disque et je vois que le .gitdossier prend vraiment 12 Go.

Comment supprimer des photos à partir de là? J'ai essayé git rm, mais échoue:

❯ git rm public/photos
fatal: pathspec 'public/photos' did not match any files

Parce que je les ai déjà supprimés du disque, mais ils sont toujours dans le .gitdossier.

J'ai essayé d'ajouter public/photosà .gitignore:

public/photos/
*.zip

Mais aucun résultat. Bien sûr, je pourrais hard reset headau moment où je n'avais pas autant de photos indésirables dans mon projet. Mais depuis, je me suis engagé à plusieurs reprises et j'ai fait beaucoup de changements dans le code.

Maxim Yefremov
la source

Réponses:

86

Dans votre cas, utilisez à la git filter-branchplace de git rm.

git rm supprimera les fichiers dans le sens où ils ne seront plus suivis par git, mais cela ne supprime pas les anciens objets de commit correspondant à ces images, et vous serez donc toujours coincé en poussant les commits précédents qui correspondent à 12 Go d'images.

Le git filter-branch, d'autre part, peut également supprimer ces fichiers de tous les commits précédents, évitant ainsi le besoin de pousser l'un d'entre eux.

  1. Utilisez la commande

    git filter-branch --force --index-filter \
      'git rm -r --cached --ignore-unmatch public/photos' \
      --prune-empty --tag-name-filter cat -- --all
    
  2. Une fois la branche de filtre terminée, vérifiez qu'aucun fichier involontaire n'a été perdu.

  3. Maintenant, ajoutez une règle .gitignore

    echo public/photos >> .gitignore
    git add .gitignore && git commit -m "ignore rule for photos"
    
  4. Maintenant fais une poussée

    git push -f origin branch
    

Vérifiez ceci , ceci et ceci pour une aide supplémentaire. Pour être plus sûr, je vous suggère de créer une copie de sauvegarde du référentiel sur votre système avant de poursuivre avec ces instructions.

Quant à votre message d'erreur d'origine, cela se produit parce que vous les avez déjà non suivis en utilisant git rm, et par conséquent, git se plaint parce qu'il ne peut pas supprimer un fichier qu'il ne suit pas. Cliquez ici pour en savoir plus .

mu 無
la source
2
Hé, je suis avec le même problème mais en tapant la commande à l'étape 1, j'obtiens une erreur: fatal: mauvaise révision '--prune-empty'. Un indice?
kevin
@kevin désolé, a manqué ce commentaire. Vous pouvez l'exécuter sans cet indicateur. L'élagage aurait supprimé tout objet de validation vide.
mu 無
1
Cette ligne ne devrait-elle pas git add .gitignore && commit -m "ignore rule for photos"êtregit add .gitignore && git commit -m "ignore rule for photos"
Cloner le
@Clone oui, ça aurait dû être ça, je l'ai corrigé maintenant :)
mu 無
1
C'est une réponse incroyablement géniale. Correction d'un problème avec mon repo depuis plusieurs années. Merci!
Moshe
18

Une réponse très simple est.

Étape 1:

Ajoutez d'abord vos fichiers non suivis que vous souhaitez supprimer:

en utilisant git add .ou git add <filename>.

Étape 2:

Puis supprimez-les facilement en utilisant la commande git rm -f <filename>ici rm = remove et -f = forcément.

Bharti Rawat
la source
cela ne fera pas ce que l'OP veut, c'est-à-dire supprimer les fichiers présents dans les commits précédents. Vous devez utiliser git filter-branchcomme mentionné ailleurs.
Simon Stevens
9

Étape 1

Ajoutez le (s) nom (s) de .gitignorefichier à votre fichier.

Étape 2

git filter-branch --force --index-filter \
    'git rm -r --cached --ignore-unmatch YOURFILE' \
    --prune-empty --tag-name-filter cat -- --all

Étape 3

git push -f origin branch

Un grand merci à @mu.

klmlfl
la source
7
... j'ai toujours pensé que git était plus dur qu'il ne devrait l'être, cela le prouve. Il n'y a aucun moyen pour quiconque de se souvenir de l'existence de la plupart des commandes git, sans parler de leurs indicateurs et de leurs bizarreries. Le modèle Git a du sens, et il fonctionne jusqu'à ce que vous suiviez un flux simple, et dès que vous êtes bloqué, vous restez coincé dur.
Muhammad Umer
2
C'est la solution qui fonctionne pour moi, j'avais besoin du--ignore-unmatch
guhur
3

utiliser cela a fonctionné pour moi

git rm -f --cached <filename>
Andreia Oliveira
la source
1

Ces chaînes fonctionnent dans mon cas:

  1. git rm -r WebApplication/packages

Il y avait une confirmation git-dialog. Vous devez choisir l'option "y".

  1. git commit -m "blabla"
  2. git push -f origin <ur_branch>
Ustin
la source
0
git stash 

a fait le travail, il a restauré les fichiers que j'avais supprimés en utilisant rmau lieu de git rm.

J'ai d'abord vérifié le dernier hachage, mais je ne pense pas que ce soit obligatoire.

user1767316
la source
0

Pour supprimer le fichier suivi et ancien commis de git, vous pouvez utiliser la commande ci-dessous. Ici, dans mon cas, je veux décompresser et supprimer tout le fichier du distrépertoire.

git filter-branch --force --index-filter 'git rm -r --cached --ignore-unmatch dist' --tag-name-filter cat -- --all

Ensuite, vous devez l'ajouter à votre .gitignoreafin qu'il ne soit plus suivi.

Kiran Maniya
la source
-1

J'avais un répertoire en double (~ web / web) et il a supprimé le duplicata imbriqué lorsque j'ai couru rm -rf webdans le premier dossier Web.

ccsinsf
la source
Pardon! J'ai dû mal lire la question. Je pensais que c'était l'objectif
visé