Jak usunąć pliki wymienione w .gitignore, ale nadal w repozytorium?

327

Mam kilka plików w moim repozytorium, które należy zignorować, dodałem je do .gitignore, ale oczywiście nie są one usuwane z mojego repozytorium.

Moje pytanie brzmi: czy istnieje magiczne polecenie lub skrypt korzystający z gałęzi filter, który może przepisać moją historię i łatwo usunąć wszystkie te pliki? A może po prostu polecenie, które utworzy zatwierdzenie, które je usunie?

Nieustraszony
źródło
3
Duplikat pliku
1
Podobne do stackoverflow.com/questions/1274057/...
testowanie
OSTRZEŻENIE: Chociaż nie usunie to fizycznego pliku z twojego lokalnego, usunie pliki z innych komputerów programistów przy następnym ściągnięciu git. Jak sprawić, by Git „zapomniał” o pliku, który był śledzony, ale jest teraz w .gitignore?
Kris Roofe,
@Stevoisiak nie jest to duplikat tego pytania, ponieważ ten pyta o WSZYSTKIE zignorowane pliki i ma również lepszą odpowiedź niż jakiekolwiek z podobnych pytań.
Omn

Odpowiedzi:

438

Możesz usunąć je z repozytorium ręcznie:

git rm --cached file1 file2 dir/file3

Lub, jeśli masz dużo plików:

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

Ale to nie działa w Git Bash w systemie Windows. Powoduje wyświetlenie komunikatu o błędzie. Następujące działa lepiej:

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

Jeśli chodzi o przepisywanie całej historii bez tych plików, bardzo wątpię, aby istniał automatyczny sposób.
Wszyscy wiemy, że przepisywanie historii jest złe, prawda? :)

Samy Dindane
źródło
2
Niestety polecenie Git Bash w systemie Windows nie działa ze ścieżkami zawierającymi spacje
Nate Bundy
19
@ Ciastko dzięki. git ls-files -i -z --exclude-from=.gitignore | xargs -0 git rm --cachedwydaje się załatwić sprawę
Nate Bundy
3
Utknąłem z tym samym problemem w systemie Windows. Korzystam z PowerShell, aw moim przypadku otrzymałem trzecie polecenie z @ samy-dindane i zmieniłem je w foreach. Stało się takgit ls-files -i --exclude-from=.gitignore | %{git rm --cached $_}
digaomatias
1
„git ls-files -i --exclude-from = .gitignore” jest bardzo pomocny, mówi mi, jakie pliki są wykluczane przez .ignore.
Owen Cao
1
Z przyjemnością znalazłem te polecenia, ALE tak naprawdę to nie usuwa plików z repozytorium. Kiedy usunąłem 2300 kB obrazów, rozmiar repozytorium spadł tylko o 10 kB. Nie można go na przykład wykorzystać do zmniejszenia repozytorium i przyspieszenia transferu.
Jan Potužník
343

Łatwiejszym sposobem, który działa na dowolnym systemie operacyjnym, jest zrobienie tego

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

Zasadniczo przeczytałeś wszystkie pliki, z wyjątkiem tych w .gitignore

gtatr
źródło
1
Jak wpływa to na innych użytkowników wykonujących ściąganie repo - gdy czytam, folder, którego nie chcemy już śledzić, jest usuwany? Jak możemy temu zapobiec - chcemy po prostu wyśledzić
snh_nl
Spowoduje to oznaczenie wszystkich plików jako zmienionych fałszywym komunikatem zatwierdzenia!
Haidar Zeineddine
3
co rozumiesz przez fałszywą wiadomość zatwierdzenia? To jest prawdziwa wiadomość zatwierdzenia: P Możesz oczywiście zmienić wiadomość, w zależności od potrzeb ...
gtatr
1
Dla kompletności potrzebujesz polecenia git push na końcu.
Mariusz Białobrzeski
1
Nie rób tego, usunie historię wszystkich plików
agrath,
144

Ponieważ pliki w .gitignore nie są śledzone, możesz użyć polecenia git clean, aby rekurencyjnie usunąć pliki, które nie są pod kontrolą wersji.

Użyj, git clean -xdnaby wykonać próbę na sucho i zobaczyć, co zostanie usunięte.
Następnie użyj, git clean -xdfaby go wykonać.

Zasadniczo git clean -hlub man git-clean(w Uniksie) da ci pomoc.

Należy pamiętać, że to polecenie spowoduje również usunięcie nowych plików , które nie znajdują się w obszarze przemieszczania.

Mam nadzieję, że to pomoże.

weiz
źródło
6
To powinna być zaakceptowana odpowiedź. To faktycznie działa (zaakceptowana odpowiedź nie działała dla mnie na macOS) i jest znacznie czystsza.
Roger Oba,
25
Ta odpowiedź nie ma zastosowania - PO twierdzi, że pliki .gitignore śledzone.
Ken Williams
20
STRZEC SIĘ! Spowoduje to trwałe usunięcie wszystkich nieśledzonych plików, a nie tylko usunięcie ich z oddziału
Emmanuel
1
git clean -xdnjest sucho, która nie usunie. następny będzie.
JohnZaj,
17
-1: To bardzo myląca odpowiedź - oryginalny plakat chciał usunąć z repozytorium, a nie całkowicie usunąć pliki. Byłem tak blisko usunięcia obciążenia plików dynamicznych wymaganych przez moje IDE, ale nie musiałem być w repozytorium.
Auspice
4

Zrobiłem bardzo proste rozwiązanie, manipulując danymi wyjściowymi instrukcji .gitignore za pomocą sed:

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

Wyjaśnienie:

  1. wydrukuj plik .gitignore
  2. usuń wszystkie komentarze z wydruku
  3. usuń wszystkie puste linie
  4. dodaj „git rm -r” na początku linii
  5. wykonać każdą linię.
Scott Crossen
źródło
10
sedjest proste?
IgorGanapolsky
0

W Linuksie możesz użyć tego polecenia:

na przykład chcę usunąć „* .py ~”, więc moim poleceniem powinno być ==>

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

Saloua SAHNOUNE
źródło
-3

Git zignoruje pliki pasujące do wzorca .gitignore po dodaniu go do .gitignore.

Ale pliki już istniejące w repozytorium będą nadal w.

służy git rm files_ignored; git commit -m 'rm no use files'do usuwania ignorowanych plików.

pensz
źródło
4
Jest ich wiele, czy istnieje sposób, aby je usunąć bez konieczności podawania ich nazwisk?
Intrepidd