Pytanie Jak sprawić, by Git "zapomniał" o pliku, który był śledzony, ale jest teraz w .gitignore?


Istnieje plik, który był śledzony przez git, ale teraz plik znajduje się na .gitignore lista.

Jednak ten plik nadal pojawia się w git status po edycji. Jak na siłę git całkowicie o tym zapomnieć?


3665
2017-08-13 19:23


pochodzenie


git clean -X brzmi podobnie, ale nie ma zastosowania w tej sytuacji (gdy pliki są nadal śledzone przez Git). Piszę to dla każdego, kto szuka rozwiązania, aby nie podążać niewłaściwą trasą. - imz -- Ivan Zakharyaschev
Jedyna prawdziwa odpowiedź na to pytanie znajduje się poniżej, patrz git update-index --assume-unchanged. To rozwiązanie 1) utrzymuje plik na serwerze (indeks), 2) pozwala go dowolnie modyfikować lokalnie. - Qwerty
Musisz użyć --skip-worktree, widzieć: stackoverflow.com/questions/13630849/... - Doppelganger
Ważne pytanie brzmi: czy plik powinien pozostać w repozytorium, czy nie? Np. Czy ktoś nowy klonuje repozytorium, czy powinien dostać plik, czy nie? Gdyby TAK następnie git update-index --assume-unchanged <file> jest poprawna, a plik pozostanie w repozytorium, a zmiany nie zostaną dodane git add. Gdyby NIE (na przykład był to jakiś plik pamięci podręcznej, wygenerowany plik itp.) git rm --cached <file> usunie go z repozytorium. - Martin
@Martin @Qwerty Everyon powinien przestać doradzać --assume-unchanged co ma na celu sprawdzenie, czy git nie sprawdza stanu dużych śledzonych plików, ale woli --skip-worktree który jest przeznaczony dla zmodyfikowanych śledzonych plików, których użytkownik nie chce już zatwierdzać. Widzieć stackoverflow.com/questions/13630849/... - Philippe


Odpowiedzi:


.gitignore zapobiegnie dodawaniu nieprzetworzonych plików (bez add -f) do zestawu plików śledzonych przez git, jednak git będzie nadal śledził wszystkie pliki, które są już śledzone.

Aby zatrzymać śledzenie pliku, musisz go usunąć z indeksu. Można to osiągnąć za pomocą tego polecenia.

git rm --cached <file>

Usunięcie pliku z wersji głównej nastąpi przy następnym zatwierdzeniu.


3887
2017-08-13 20:40



proces, który działał dla mnie, to 1. zatwierdzić oczekujące zmiany jako pierwsze 2. git rm --cached <plik> i ponownie zatwierdzić 3. dodać plik do .gitignore, sprawdzić status git i zatwierdzić ponownie - mataal
Bardzo ważne dodawanie. Jeśli plik, który jest ignorowany, zostanie zmodyfikowany (ale mimo to nie powinien być zatwierdzony), po modyfikacji i uruchomieniu git add . zostanie dodany do indeksu. A następne zatwierdzenie zostanie przypisane do repozytorium. Aby tego uniknąć, zaraz po tym wszystkim mataal powiedział jeszcze jedno polecenie: git update-index --assume-unchanged <path&filename> - Dao
Metoda @AkiraYamamoto również dobrze się sprawdziła. W moim przypadku pominąłem wynik, ponieważ moje repozytorium zawierało tysiące plików: git rm -r -q --cached . - Aaron Blenkush
Spowoduje to usunięcie pliku git pull chociaż. - Petr Peller
git rm --cached <plik> po prostu usuń plik z repozytorium, git update-index --assume-unchanged <plik> nie pokazany plik w niezaprogramowanych zmianach i nie powoduje pobrania nowych zmian. Ale chcę GIT JUST IGNORE CONTENT PLEATEASE PLIKU - Igor Semin


Poniższa seria poleceń spowoduje usunięcie wszystkich elementów z indeksu Git (nie z katalogu roboczego lub lokalnego repozytorium), a następnie aktualizację indeksu Git przy jednoczesnym przestrzeganiu ignorowania git. PS. Indeks = Pamięć podręczna

Pierwszy:

git rm -r --cached . 
git add .

Następnie:

git commit -am "Remove ignored files"

1997
2017-09-30 13:51



Aby podkreślić różnicę między tą odpowiedzią a akceptowaną: Korzystanie z tych poleceń nie wymaga znajomości plików, których dotyczy problem. (Wyobraź sobie tymczasowy katalog z mnóstwem losowych plików, które powinny zostać usunięte z indeksu). - Ludwig
To samo, co zaakceptowana odpowiedź. Pliki zostaną usunięte na git pull. - Petr Peller
Byłoby miło mieć to jako standardowe polecenie git. Coś jak git rmignored. - Berik
@gudthing -r oznacza "rekursywny" - Monkey King
Dzięki temu możesz skończyć dodając inny niepotrzebne pliki, których obecnie nie ma .gitignore. Które mogą być trudne do uzyskania, jeśli zależy od tego, jak hałas git status jest po tym poleceniu. Polecenie, które tylko usuwa świeżo zignorowane pliki byłyby lepsze. Dlatego wolę odpowiedź ThSoft - KurzedMetal


git update-index wykonuje to za mnie:

git update-index --assume-unchanged <file>

Uwaga: To rozwiązanie jest w rzeczywistości niezależne .gitignore jak gitignore jest tylko dla nieśledzonych plików.

edytować: Od momentu opublikowania tej odpowiedzi utworzono nową opcję, która powinna być preferowana. Powinieneś użyć --skip-worktree która jest przeznaczona dla zmodyfikowanych śledzonych plików, których użytkownik nie chce już popełniać i przechowywać --assume-unchanged dla wydajności, aby uniemożliwić git sprawdzenie statusu dużych śledzonych plików. Widzieć https://stackoverflow.com/a/13631525/717372 po więcej szczegółów...


740
2017-11-27 11:24



To JEST prawdziwa odpowiedź. Niesamowite, bardzo proste, nie zanieczyszcza git status a właściwie bardzo intuicyjny. Dzięki. - Pablo Olmos de Aguilera C.
Poszedłem wystarczająco dobrze rm [...] . rozwiązanie, jako że przynajmniej mogłem pojąć, jak to działało. Nie znalazłem żadnej świetnej dokumentacji na temat czego update-index & --assume-unchanged zrobić. Czy ktoś może dodać, jak to się ma do porównania, skoro chciałbym usunąć wszystkie pliki, które zostałyby zignorowane? (Lub link do wyjaśnienia?) - Brady Trainor
git update-index --assume-unchanged <path> … spowoduje, że git zignoruje zmiany w podanych ścieżkach, niezależnie od .gitignore. Jeśli pobierzesz z pilota, a pilot zdąży zmienić tę ścieżkę, git nie powie scaleniu z konfliktem i będziesz musiał scalić ręcznie. git rm --cached <path> … spowoduje, że git przestanie śledzić tę ścieżkę. Jeśli nie dodasz ścieżki do .gitignore zobaczysz ścieżkę w przyszłości git status. Pierwsza opcja ma mniejszy hałas w historii zatwierdzania git i pozwala na zmiany w pliku "zignorowanym", który ma być dystrybuowany w przyszłości. - ManicDee
Cofnij, używając: git update-index --no-assume-unchanged <plik> - xgMz
Jestem bardzo zdezorientowany, jak to nie jest zaakceptowana odpowiedź. Zaakceptowana tu odpowiedź wyraźnie nie odpowiada na faktyczne pytanie. Ta odpowiedź ignoruje zmiany w pliku znajdującym się w repozytorium, ale nie usuwa go z repozytorium. - Dave Cooper


git ls-files --ignored --exclude-standard -z | xargs -0 git rm --cached
git commit -am "Remove ignored files"

Spowoduje to pobranie listy ignorowanych plików i usunięcie ich z indeksu, a następnie zatwierdzenie zmian.


218
2018-05-23 22:29



Jeśli chcesz je również usunąć z katalogu roboczego, po prostu uruchom git ls-files --ignored --exclude-standard | xargs git rm . Uważam, że ta odpowiedź jest najlepsza! Ponieważ jest bardzo przejrzysty, w systemie Unix i robi to, co chce, w sposób bezpośredni, bez komponowania efektów ubocznych innych, bardziej złożonych poleceń. - imz -- Ivan Zakharyaschev
Świetna odpowiedź; jednak polecenie zakończy się niepowodzeniem, jeśli istnieją ścieżki ze spacjami po środku, np .: "My dir / my_ignored_file.txt" - David Hernandez
git ls-files --ignored --exclude-standard | sed 's /.*/"&"/' | xargs git rm --cached - David Hernandez
git rm będzie narzekać, jeśli ls-files nic nie pasuje. Posługiwać się xargs -r git rm ... powiedzieć xargs nie biec git rm jeśli nie pasują żadne pliki. - Wolfgang
Byłoby lepiej użyć \ 0 jako separatora: git ls-files --ignored --exclude-standard -z|xargs -0 git rm --cached - Nils-o-mat


Zawsze używam tego polecenia, aby usunąć te nieśledzone pliki. Jednowierszowe, uniksowe, czyste wyjście:

git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached

Wyświetla listę wszystkich zignorowanych plików, zastępuje każdą linię wyjściową cytowaną linią, aby obsługiwać ścieżki ze spacjami w środku i przekazywać wszystko do git rm -r --cached aby usunąć ścieżki / pliki / katalogi z indeksu.


60
2018-06-19 15:42



Świetne rozwiązanie! Działa perfekcyjnie i wydaje się bardziej poprawne, że usuwa wszystkie pliki, a następnie dodaje je z powrotem. - Jon Catmull
Ja też uważałem to za "najczystsze". To może być oczywiste, ale wystarczy uruchomić pierwszą część, git ls-files --ignored --exclude-standard, na własną rękę pozwala ci najpierw zrozumieć / sprawdzić, jakie pliki twoje nowe .gitignore zamierza wykluczyć / usunąć, zanim przejdziesz dalej i wykonać finał git rm. - JonBrave
Pamiętaj, że w nazwach plików nie występują pewne "nieprzyjemne" znaki, np. \n. Napisałem swoje rozwiązanie, aby to uwzględnić. - JonBrave
Kolejne zastrzeżenie: na wyciągnięcie, spowoduje to, że plik zostanie usunięty w innych roboczych katalogach, prawda? - LarsH


Jeśli nie możesz git rm śledzony plik, ponieważ inne osoby mogą go potrzebować (ostrzeżenie, nawet jeśli ty  git rm --cached, gdy ktoś inny otrzyma tę zmianę, ich pliki zostaną usunięte w ich systemie plików), spójrz na https://gist.github.com/1423106 na sposoby, w jakie ludzie pracowali nad problemem.


49
2017-07-19 00:08



git nie usunąłby pliku, gdyby był brudny w momencie kasowania. A jeśli to nie jest brudne, pobieranie pliku będzie tak proste, jak git checkout <oldref> -- <filename> - ale potem zostanie wyewidencjonowany i zignorowany. - amenthes
Chociaż może to teoretycznie odpowiedzieć na pytanie, byłoby lepiej aby uwzględnić istotne części odpowiedzi tutaj, i podać link do odniesienia. Widzieć tutaj aby uzyskać instrukcje, jak pisać lepszy odpowiedzi "oparte na łączu". Dzięki! - GhostCat
Tylko mówię. 5-letnia odpowiedź i 45 przegranych, ale nikt nie odważy się powiedzieć "tylko linki są złe?" - GhostCat


przenieś go, zatwierdz, a następnie prześlij z powrotem. To działało dla mnie w przeszłości. Prawdopodobnie istnieje "giętszy" sposób, aby to osiągnąć.


44
2017-08-13 19:27



To zadziałało, jeśli chcesz zignorować kilka plików, które wcześniej nie były ignorowane. Chociaż, tak jak powiedziałeś, prawdopodobnie istnieje lepszy sposób na to. - Oskar Persson
Dokładnie to zrobiłem. Po prostu przenieś pliki do folderu poza git, następnie wykonaj "git add.", "Git commit". (To usunęło pliki), a następnie dodaj gitignore, odwołując się do plików / folderów, zatwierdz ponownie, aby dodać plik gitignore do git, a następnie skopiuj / przenieś z powrotem do folderów i powinny one zostać zignorowane. Uwaga: okaże się, że pliki zostały usunięte z GIT, więc prawdopodobnie usunęłoby je z innych kas / pullów, jak wspomniano w powyższych rozwiązaniach, ale skoro robisz ich kopie na początku, to nie jest to kwestia IMHO. daj znać reszcie zespołu ... - Del
Jest to najprostszy sposób na pozbycie się błędnie zatwierdzonych folderów. - Martlark
Wydaje się być jedyną drogą, którą widzę. Jest to ogromny błąd (nie "funkcja") w git, który zaraz po dodaniu pliku / folderu do .gitignore, nie tylko zignoruje ten plik z tego miejsca - na zawsze - wszędzie. - JosephK


Co dla mnie nie działa

(Pod Linuksem), chciałem skorzystać z postów sugerujących ls-files --ignored --exclude-standard | xargs git rm -r --cached podejście. Jednak (niektóre) pliki do usunięcia miały wbudowany znak nowej linii / LF /\n w ich nazwiskach. Żadne z rozwiązań:

git ls-files --ignored --exclude-standard | xargs -d"\n" git rm --cached
git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached

poradzić sobie z tą sytuacją (pojawiają się błędy dotyczące plików, które nie zostały znalezione).

Więc oferuję

git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached

To wykorzystuje -z argument do ls-filesi -0 argument do xargs aby bezpiecznie / poprawnie obsłużyć "nieprzyjemne" znaki w nazwach plików.

Na stronie podręcznika pliki git-ls (1), w Stanach:

Gdy opcja -z nie jest używana, znaki TAB, LF i ukośnik odwrotny w   Ścieżki są reprezentowane odpowiednio jako \ t, \ n i \\.

więc myślę, że moje rozwiązanie jest potrzebne, jeśli nazwy plików mają w sobie dowolne z tych znaków.

EDYCJA: Poproszono mnie o dodanie tego - jak każdy inny git rm polecenie --- po tym musi nastąpić a popełnić aby trwale usunąć, np. git commit -am "Remove ignored files".


37
2017-12-29 12:50



Dla mnie jest to najlepsze rozwiązanie. Ma znacznie lepszą wydajność niż git add .. Zawiera również najlepsze ulepszenia z niektórych komentarzy powyżej. - Nils-o-mat
Świetne rozwiązanie i działa bardzo dobrze - smac89
Przetworzył prezent - usunął pliki z białymi znakami w nazwach poprawnie. - Dave Walker
Czy możesz dodać ThSoft git commit -am "Remove ignored files" potem do twojej odpowiedzi? Twoje odpowiedzi razem doprowadziły mnie do rzeczy: j - kando


Osiągnąłem to, używając git - gałąź filtru. Dokładne polecenie, którego użyłem, zostało zaczerpnięte ze strony podręcznika:

OSTRZEŻENIE: spowoduje to usunięcie pliku z całej historii

git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD

To polecenie odtworzy całą historię commitów, wykonując git rm przed każdym zatwierdzeniem, a więc pozbędzie się określonego pliku. Nie zapomnij wykonać kopii zapasowej przed uruchomieniem polecenia w tym momencie będzie być zagubionym.


34
2017-08-13 19:35



Spowoduje to zmianę wszystkich identyfikatorów zatwierdzania, a tym samym przerwanie łączenia z gałęzi spoza kopii repozytorium. - bdonlan
OSTRZEŻENIE: spowoduje to usunięcie pliku z całej historii. Tego właśnie szukałem, aby usunąć całkowicie niepotrzebny i zbyt duży plik (który nigdy nie powinien był zostać zatwierdzony), który został popełniony dawno temu w historii wersji. - zebediah49