git rm - fatal: pathspec nie pasuje do żadnych plików

87

Dodałem przypadkowo ponad 9000 zdjęć do folderu mojego projektu. I popełnił ich. Następnie usunąłem je z dysku. Zobowiązany.

Teraz próbuję wypchnąć zmiany na serwer git. Ale trwa to zbyt długo i próbuje wysłać 12 Gb danych.

Sprawdziłem rozmiar plików na dysku i widzę, że .gitfolder naprawdę zajmuje 12 GB.

Jak usunąć stamtąd zdjęcia ? Próbowałem git rm, ale mi się nie udało:

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

Ponieważ już je usunąłem z dysku, ale nadal są w .gitfolderze.

Próbowałem dodać public/photosdo .gitignore:

public/photos/
*.zip

Ale bez rezultatu. Oczywiście mogłem hard reset headdo momentu, kiedy nie miałem tylu śmieciowych zdjęć w swoim projekcie. Ale od tego czasu popełniałem wiele razy i wprowadzałem wiele zmian w kodzie.

Maxim Yefremov
źródło

Odpowiedzi:

86

W twoim przypadku użyj git filter-branchzamiast git rm.

git rm usunie pliki w tym sensie, że nie będą już śledzone przez git, ale to nie usunie starych obiektów zatwierdzonych odpowiadających tym obrazom, więc nadal będziesz utknął z wypychaniem wcześniejszych zatwierdzeń, które odpowiadają 12 GB obrazów.

Z git filter-branchdrugiej strony, może usunąć te pliki ze wszystkich poprzednich zatwierdzeń, eliminując w ten sposób potrzebę wypychania któregokolwiek z nich.

  1. Użyj polecenia

    git filter-branch --force --index-filter \
      'git rm -r --cached --ignore-unmatch public/photos' \
      --prune-empty --tag-name-filter cat -- --all
    
  2. Po ukończeniu gałęzi filtru sprawdź, czy żaden niezamierzony plik nie został utracony.

  3. Teraz dodaj regułę .gitignore

    echo public/photos >> .gitignore
    git add .gitignore && git commit -m "ignore rule for photos"
    
  4. Teraz pchnij

    git push -f origin branch
    

Sprawdź to , to i to, aby uzyskać dalszą pomoc. Aby być bezpieczniejszym, sugerowałbym utworzenie kopii zapasowej repozytorium w systemie przed wykonaniem tych instrukcji.

Jeśli chodzi o twój pierwotny komunikat o błędzie, dzieje się tak, ponieważ już je usunąłeś, używając git rm, a zatem git narzeka, ponieważ nie może usunąć pliku, którego nie śledzi. Przeczytaj więcej na ten temat tutaj .

mu 無
źródło
2
Hej, mam ten sam problem, ale podczas wpisywania polecenia w kroku 1 pojawia się błąd: fatal: bad revision '--prune-empty'. Jakaś wskazówka?
kevin
@kevin przepraszam, przegapiłem ten komentarz. Możesz go uruchomić bez tej flagi. Przycinanie spowodowałoby usunięcie dowolnego pustego obiektu zatwierdzenia.
mu 無
1
Nie powinno tak git add .gitignore && commit -m "ignore rule for photos"byćgit add .gitignore && git commit -m "ignore rule for photos"
Clone
@Clone tak, powinno być to, poprawiłem to teraz :)
mu 無
1
To niesamowicie niesamowita odpowiedź. Naprawiono problem, który miałem z moim repozytorium od kilku lat. Dzięki!
Moshe
18

Bardzo prosta odpowiedź brzmi.

Krok 1:

Najpierw dodaj nieśledzone pliki, które chcesz usunąć:

za pomocą git add .lub git add <filename>.

Krok 2:

Następnie usuń je łatwo, używając polecenia git rm -f <filename>tutaj rm = remove i -f = forcely.

Bharti Rawat
źródło
nie zrobi to tego, czego chce OP, czyli usunięcia plików obecnych w poprzednich zatwierdzeniach. Musisz użyć, git filter-branchjak wspomniano w innym miejscu.
Simon Stevens,
9

Krok 1

Dodaj nazwy plików do swojego .gitignorepliku.

Krok 2

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

Krok 3

git push -f origin branch

Wielkie dzięki dla @mu.

klmlfl
źródło
7
... zawsze myślałem, że git jest trudniejszy niż powinien, to dowodzi. Nie ma sposobu, aby ktokolwiek mógł nawet zapamiętać istnienie większości poleceń git, nie mówiąc już o ich flagach i dziwactwach. Model Git ma sens i działa, dopóki nie wykonasz prostego przepływu, a gdy tylko utkniesz, utkniesz mocno.
Muhammad Umer
2
To jest rozwiązanie, które działa dla mnie, potrzebowałem--ignore-unmatch
guhur
3

używanie tego zadziałało dla mnie

git rm -f --cached <filename>
Andreia Oliveira
źródło
1

Te łańcuchy działają w moim przypadku:

  1. git rm -r WebApplication/packages

Pojawiło się potwierdzenie git-dialog. Należy wybrać opcję „y”.

  1. git commit -m "blabla"
  2. git push -f origin <ur_branch>
Ustin
źródło
0
git stash 

wykonał zadanie, przywrócił pliki, które usunąłem, używając rmzamiast git rm.

Najpierw sprawdziłem ostatni hash, ale nie sądzę, żeby to było wymagane.

user1767316
źródło
0

Aby usunąć śledzony i stary zatwierdzony plik z gita, możesz użyć poniższego polecenia. Tutaj w moim przypadku chcę odśledzić i usunąć cały plik z distkatalogu.

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

Następnie musisz dodać go do swojego, .gitignoreaby nie był dalej śledzony.

Kiran Maniya
źródło
-1

Miałem zduplikowany katalog (~ web / web) i usunąłem zagnieżdżony duplikat, gdy uruchomiłem rm -rf webw pierwszym folderze sieciowym.

ccsinsf
źródło
Przepraszam! Musiałem źle odczytać pytanie. Myślałem, że taki był cel
ccsinsf