git clean -Xbrzmi podobnie, ale nie ma zastosowania w tej sytuacji (gdy pliki są nadal śledzone przez Git). Piszę to dla każdego, kto szuka rozwiązania, które nie podąży niewłaściwą drogą.
imz - Ivan Zakharyaschev
35
Jedyną prawdziwą odpowiedzią na to pytanie jest poniżej git update-index --assume-unchanged. To rozwiązanie 1) utrzymuje plik na serwerze (indeks), 2) pozwala swobodnie go modyfikować lokalnie.
Ważnym pytaniem jest: czy plik powinien pozostać w repozytorium, czy nie? Na przykład, jeśli ktoś nowy klonuje repozytorium, powinien otrzymać plik, czy nie? Jeśli TAK następnie git update-index --assume-unchanged <file>jest poprawny, a plik pozostanie w repozytorium, a zmiany nie zostaną dodane git add. Jeśli NIE (na przykład był to jakiś plik pamięci podręcznej, wygenerowany plik itp.), git rm --cached <file>Usunie go z repozytorium.
Martin
9
@Martin @Qwerty Everyon powinien przestać doradzać, w --assume-unchangedkwestii wydajności, aby git nie sprawdzał statusu dużych śledzonych plików, ale preferuje --skip-worktreeto, co dotyczy zmodyfikowanych plików śledzonych, których użytkownik nie chce już zatwierdzać. Zobacz stackoverflow.com/questions/13630849/...
Philippe
Odpowiedzi:
5690
.gitignorezapobiegnie dodawaniu nieśledzonych 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>
Jeśli chcesz usunąć cały folder, musisz usunąć z niego wszystkie pliki rekurencyjnie.
git rm -r --cached <folder>
Usunięcie pliku z rewizji głównej nastąpi przy następnym zatwierdzeniu.
OSTRZEŻENIE: Chociaż nie usunie to fizycznego pliku z twojego lokalnego, usunie pliki z innych komputerów programistów na następnym git pull.
proces, który działał dla mnie był 1. zatwierdzić najpierw oczekujące zmiany 2. git rm - buforowany <plik> i zatwierdzić ponownie 3. dodać plik do .gitignore, sprawdzić status git i zatwierdzić ponownie
mataal
117
Bardzo ważne dodanie. Jeśli plik, który jest ignorowany, zostanie zmodyfikowany (ale mimo to nie powinien zostać zatwierdzony), po modyfikacji i wykonaniu git add .zostanie dodany do indeksu. A następne zatwierdzenie zatwierdziłoby to do repozytorium. Aby tego uniknąć, zaraz po tym wszystkim mataal powiedział jeszcze jedno polecenie:git update-index --assume-unchanged <path&filename>
Dao
32
Metoda @AkiraYamamoto również działała dobrze dla mnie. W moim przypadku git rm -r -q --cached .
pominąłem
85
Spowoduje to jednak usunięcie pliku git pull.
Petr Peller
22
git rm --cached <plik> po prostu usuń plik z repozytorium, git update-index --assume-unchanged <plik> nie pokazano pliku w nieustawionych zmianach i nie powoduje pobrania nowych zmian. Ale chcę, żeby GIT JUŻ Zignorował zawartość pliku PLEEEEEASE
Igor Semin
2608
Poniższa seria poleceń usunie wszystkie elementy z Git Index (nie z katalogu roboczego lub lokalnego repozytorium), a następnie zaktualizuje Git Index, przestrzegając ignorowania git. PS. Indeks = pamięć podręczna
Aby podkreślić różnicę między tą odpowiedzią a odpowiedzią: Za pomocą tych poleceń nie trzeba tak naprawdę znać plików, których dotyczy problem. (Wyobraź sobie tymczasowy katalog z dużą ilością losowych plików, które powinny zostać usunięte z indeksu).
Ludwig
53
Taki sam jak zaakceptowana odpowiedź. Pliki zostaną usunięte w dniu git pull.
Petr Peller
73
Byłoby miło mieć to jako standardowe polecenie git. Coś jak git rmignored.
Berik,
12
@gudthing -r oznacza „rekurencyjny”
Mark
14
Dzięki temu możesz w końcu dodać inne bezużyteczne pliki, których obecnie nie ma .gitignore. Które może być trudne do ustalenia, jeśli zależy od tego, jaki hałas git statuswystępuje po tym poleceniu. Polecenie, które usuwa tylko nowo zignorowane pliki, byłoby lepsze. Dlatego wolę odpowiedź
thSoft
1122
git update-index wykonuje dla mnie zadanie:
git update-index --assume-unchanged <file>
Uwaga: To rozwiązanie jest w rzeczywistości niezależne, .gitignoreponieważ gitignore jest przeznaczony tylko dla nieśledzonych plików.
edycja: Od czasu opublikowania tej odpowiedzi utworzono nową opcję, którą należy preferować. Powinieneś użyć tego, --skip-worktreeco jest dla zmodyfikowanych plików śledzonych, których użytkownik nie chce już zatwierdzać i zachować --assume-unchangedwydajność, aby git nie sprawdzał statusu dużych plików śledzonych. Zobacz szczegóły na https://stackoverflow.com/a/13631525/717372 ...
To jest prawdziwa odpowiedź. Niesamowite, bardzo proste, nie zanieczyszcza środowiska git statusi jest bardzo intuicyjne. Dzięki.
Pablo Olmos de Aguilera C.
4
Poszedłem do wystarczająco dobrego rm [...] .rozwiązania, ponieważ przynajmniej mogłem sobie wyobrazić, jak to działa. Nie znalazłem świetnej dokumentacji na temat tego, co update-indexi --assume-unchangedrobię. Czy ktoś może dodać, jak to się ma do innych, ponieważ chciałbym usunąć wszystkie pliki, które zostałyby zignorowane? (Lub link do jasnego wyjaśnienia?)
Brady Trainor
25
git update-index --assume-unchanged <path> …spowoduje, że git zignoruje zmiany w określonych ścieżkach, niezależnie od .gitignore. Jeśli pobierzesz z pilota, a ten pilot ma zmiany w tej ścieżce, git nie powiedzie scalenia 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 .gitignore, zobaczysz ją w przyszłości git status. Pierwsza opcja ma mniej hałasu w historii zatwierdzeń git i pozwala na rozpowszechnianie zmian w pliku „ignorowanym” w przyszłości.
ManicDee,
26
Jestem dość zdezorientowany, że nie jest to akceptowana odpowiedź. Przyjęta tutaj odpowiedź wyraźnie nie odpowiada na zadane pytanie. Ta odpowiedź ignoruje zmiany w pliku znajdującym się w repozytorium, ale nie usuwa go z repozytorium.
Dave Cooper
11
Ta odpowiedź byłaby o wiele bardziej przydatna, gdyby dokładnie wyjaśniła, co robi dane polecenie, np. Czym różni się od innych sugerowanych rozwiązań.
Jeśli chcesz je również usunąć z katalogu roboczego, po prostu uruchom git ls-files --ignored --exclude-standard | xargs git rm . Wierzę, że ta odpowiedź jest najlepsza! Ponieważ jest to bardzo jasne, w stylu uniksowym i robi pożądaną rzecz w bezpośredni sposób, bez komponowania skutków ubocznych innych, bardziej złożonych poleceń.
imz - Ivan Zakharyaschev
6
Świetna odpowiedź; jednak polecenie nie powiedzie się, jeśli masz ścieżki ze spacjami na środku, np .: „Mój katalog / mój_plik_plików.txt”
Zawiera listę wszystkich zignorowanych plików, zamiast tego zastępuje każdą linię wyjściową linią cytowaną, aby obsługiwać ścieżki ze spacjami w środku, i przekazuje wszystko, git rm -r --cachedaby usunąć ścieżki / pliki / katalogi z indeksu.
Świetne rozwiązanie! Działa idealnie i wydaje się bardziej poprawne niż usuwanie wszystkich plików, a następnie dodawanie ich z powrotem.
Jon Catmull
5
Ja też uważam to za „najczystsze”. Może to być oczywiste, ale samo uruchomienie pierwszej części git ls-files --ignored --exclude-standardpozwala najpierw zrozumieć / zweryfikować, jakie pliki .gitignorezostaną wykluczone / usunięte przez nowy , zanim przejdziesz dalej i wykonasz finał git rm.
JonBrave,
Należy pamiętać, że w nazwach plików występują błędy, które zawierają pewne „nieprzyjemne” znaki, np \n. Zamieściłem moje rozwiązanie, aby to zrobić.
JonBrave,
3
Kolejne zastrzeżenie: po pociągnięciu spowoduje to usunięcie pliku w katalogach roboczych innych osób, prawda?
LarsH,
próbowałem, ale nie działało dla mnie: sed: 1: "s/.*/": unterminated substitute in regular expressionw poleceniu filter-branch na repozytorium ze spacjami. (Wydaje się, że działa poza gałęzią filtrów). Kiedyś git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cachedz @ JonBrave za odpowiedź zamiast.
goofology,
70
przenieś to, zatwierdz, a następnie przenieś z powrotem. To działało dla mnie w przeszłości. Prawdopodobnie istnieje bardziej „bardziej gitarzysta” sposób na osiągnięcie tego.
Działa to świetnie, jeśli chcesz zignorować kilka plików, które nie były wcześniej ignorowane. Chociaż, jak powiedziałeś, prawdopodobnie jest na to lepszy sposób.
Oskar Persson
Właśnie to zrobiłem. Po prostu przenieś pliki do folderu poza git, a 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, zatwierdź ponownie, aby dodać plik gitignore do git, a następnie skopiuj / przenieś z powrotem do folderów i należy je zignorować. Uwaga: wygląda na to, że pliki zostały usunięte z GIT, więc prawdopodobnie usunę je z innych kas / wyciągów, jak wspomniano w powyższych rozwiązaniach, ale ponieważ robisz ich kopie na początku, nie jest to tak duży problem IMHO. daj znać reszcie zespołu ...
Del
Jest to najprostszy sposób na pozbycie się nieprawidłowo popełnionych folderów.
Martlark,
1
Wydaje się, że to jedyny sposób, który widzę. Jest to ogromny błąd (nie „funkcja”) w git, który po dodaniu pliku / folderu do .gitignore nie tylko ignoruje ten plik od tego momentu - na zawsze - wszędzie.
JosephK
Działa
66
Jeśli nie możesz git rmśledzić pliku, ponieważ inne osoby mogą go potrzebować (ostrzeżenie, nawet jeśli Tygit rm --cached , gdy ktoś inny dostanie tę zmianę, jego pliki zostaną usunięte w systemie plików). Często są one wykonywane z powodu nadpisywania plików konfiguracyjnych, poświadczeń uwierzytelnienia itp. Informacje na temat sposobów obejścia problemu można znaleźć na stronie https://gist.github.com/1423106 .
Podsumowując:
Niech Twoja aplikacja wyszuka zignorowany plik config-overide.ini i użyje go w zatwierdzonym pliku config.ini (lub alternatywnie poszukaj ~ / .config / myapp.ini lub $ MYCONFIGFILE)
Zatwierdź plik config-sample.ini i zignoruj plik config.ini, w razie potrzeby przygotuj skrypt lub podobną kopię pliku.
Spróbuj użyć gitattributes clean / smudge magic, aby zastosować i usunąć zmiany, na przykład rozmazuj plik konfiguracyjny jako kasa z alternatywnej gałęzi i wyczyść plik konfiguracyjny jako kasa z HEAD. To trudne zadanie, nie polecam go początkującym użytkownikom.
Zachowaj plik konfiguracyjny w dedykowanym oddziale wdrażania, który nigdy nie jest scalany z głównym. Kiedy chcesz wdrożyć / skompilować / przetestować, łączysz się z tym oddziałem i dostajesz ten plik. Jest to zasadniczo podejście do rozmazywania / czyszczenia, z wyjątkiem korzystania z zasad scalania przez ludzi i modułów dodatkowych.
Anti-recommentation: Nie używaj zakładania niezmienionego, skończy się to tylko łzami (ponieważ kłamstwo samo w sobie spowoduje złe rzeczy, takie jak zmiana utracona na zawsze).
git nie usunąłby pliku, gdyby był brudny w momencie usuwania. A jeśli nie jest brudny, odzyskanie pliku byłoby tak proste, jak git checkout <oldref> -- <filename>- ale wtedy zostanie sprawdzone i zignorowane.
amenthes
Jeśli chodzi o twoją ostatnią uwagę (około --assume-unchanged): albo jest to kult ładunku i powinien zostać odrzucony, albo możesz wyjaśnić, dlaczego (o czym jestem przekonany) i stanie się przydatny.
Załóżmy, że już dodałeś / zatwierdziłeś niektóre pliki do swojego repozytorium git, a następnie dodajesz je do swojego .gitignore; pliki te będą nadal obecne w indeksie repozytorium. W tym artykule zobaczymy, jak się ich pozbyć.
Krok 1: Zatwierdź wszystkie zmiany
Przed kontynuowaniem upewnij się, że wszystkie zmiany zostały zatwierdzone, w tym plik .gitignore.
Nie usunie plików ze zdalnego repozytorium? Co jeśli chcę zachować pliki zarówno w repozytorium lokalnym, jak i repozytorium zdalnym, ale sprawić, aby git „zapomniał” o nich?
Avishay28
AFAIK to nie usunie plików z historii, ponieważ nie używamy żadnych poleceń zmieniających historię (popraw mnie, jeśli się mylę). To tylko dodaje nowe zatwierdzenie, usuwając pliki ignorowane w gitignore z git. Te pliki będą tam w historyczne zobowiązania
Dheeraj Bhaskar
49
Osiągnąłem to za pomocą git filter-branch . Dokładne polecenie, którego użyłem, pochodzi 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ę zatwierdzeń, wykonując git rmprzed każdym zatwierdzeniem, a zatem usunie określony plik. Nie zapomnij wykonać kopii zapasowej przed uruchomieniem polecenia, ponieważ zostanie utracone.
Spowoduje to zmianę wszystkich identyfikatorów zatwierdzeń, a tym samym zerwanie scalania z oddziałów poza kopią repozytorium.
bdonlan,
19
OSTRZEŻENIE: spowoduje to usunięcie pliku z całej historii. Właśnie tego szukałem, aby usunąć całkowicie niepotrzebny i zbyt duży plik (dane wyjściowe, które nigdy nie powinny były zostać zatwierdzone), który został popełniony dawno temu w historii wersji.
zebediah49 13.03.13
48
Co mi nie zadziałało
(Pod Linuksem) chciałem użyć tutaj postów sugerujących takie ls-files --ignored --exclude-standard | xargs git rm -r --cachedpodejście. Jednak (niektóre) pliki, które mają zostać usunięte, miały osadzoną nową linię / LF / \nw swoich nazwach. Żadne z rozwiązań:
Co powiesz na zaniżone ze względu na fakt, że tak naprawdę nie zadziała, ponieważ potrzebujesz -r, aby zrestartować rekurencyjnie :) (Ktoś nie skopiował poprawnie)
Aran Mulholland
1
Ostrzeżenie: Ta technika nie powoduje, że git zignoruje plik, zamiast tego powoduje, że git usuwa plik. Oznacza to, że jeśli użyjesz tego rozwiązania, za każdym razem, gdy ktokolwiek spróbuje pobrać git, plik zostanie usunięty. Więc to nie jest faktycznie ignorowane. Zobacz rozwiązanie sugerujące git update-index --assume-niezmienione zamiast rozwiązania pierwotnego pytania.
Ten problem nie występuje na przykład podczas korzystania z CVS. CVS przechowuje informacje jako listę zmian opartych na plikach. Informacje dla CVS to zestaw plików i zmiany wprowadzane w każdym pliku w czasie.
Ale w Git za każdym razem, gdy zatwierdzasz lub zapisujesz stan swojego projektu, zasadniczo robi zdjęcie, jak wyglądają wszystkie twoje pliki w tym momencie i przechowuje odniesienie do tej migawki. Tak więc, jeśli dodałeś plik raz, zawsze będzie on obecny w tej migawce.
Na tej podstawie wykonuję następujące czynności, jeśli plik jest już śledzony:
git update-index --skip-worktree <file>
Od tego momentu wszystkie lokalne zmiany w tym pliku będą ignorowane i nie będą przekazywane zdalnie. Jeśli plik zostanie zmieniony zdalnie, nastąpi konflikt, kiedy git pull. Skrytka nie będzie działać. Aby rozwiązać ten problem, skopiuj zawartość pliku w bezpieczne miejsce i wykonaj następujące kroki:
Zawartość pliku zostanie zastąpiona treścią zdalną. Wklej zmiany z bezpiecznego miejsca do pliku i wykonaj ponownie:
git update-index --skip-worktree <file>
Jeśli wszyscy, którzy pracują z projektem, wykonają git update-index --skip-worktree <file>, problemy pullpowinny być nieobecne. To rozwiązanie jest odpowiednie dla plików konfiguracyjnych, gdy każdy programista ma własną konfigurację projektu.
Nie jest to wygodne za każdym razem, gdy plik jest zmieniany na pilocie, ale może chronić go przed nadpisaniem przez zawartość zdalną.
Wykonaj kolejno następujące kroki, wszystko będzie dobrze.
1. usuń błędnie dodane pliki z katalogu / magazynu . Możesz użyć polecenia „rm -r” (dla systemu Linux) lub usunąć je, przeglądając katalogi. Lub przenieś je w inne miejsce na komputerze. [Może być konieczne zamknięcie IDE, jeśli uruchamiasz w celu przeniesienia / usunięcia ]
2. dodaj pliki / katalogi do gitignorepliku teraz i zapisz go.
3. teraz usuń je z pamięci podręcznej git za pomocą tych poleceń (jeśli istnieje więcej niż jeden katalog, usuń je jeden po drugim, powtarzając to polecenie)
git rm -r --cached path-to-those-files
4.Now zrobić popełnić i Push , użyj tych poleceń. Spowoduje to usunięcie tych plików ze zdalnego programu git i spowoduje, że git przestanie śledzić te pliki.
Odpowiedź Matta Feara była najskuteczniejsza IMHO. Poniżej znajduje się tylko skrypt PowerShell dla tych w systemie Windows, aby usuwać tylko pliki z repozytorium git, które pasują do ich listy wykluczeń.
W jakiej sytuacji ta lista plików nie będzie równa rekurencyjnej - buforowanej?
John Zabroski
8
Przenieś lub skopiuj plik w bezpieczne miejsce, aby go nie zgubić. Następnie uruchom plik i zatwierdź. Plik będzie nadal wyświetlany, jeśli powrócisz do jednego z wcześniejszych zatwierdzeń lub do innej gałęzi, w której nie został usunięty. Jednak we wszystkich przyszłych zatwierdzeniach plik nie będzie ponownie wyświetlany. Jeśli plik znajduje się w git ignoruj, możesz przenieść go z powrotem do folderu, a git go nie zobaczy.
BFG został zaprojektowany specjalnie do usuwania niechcianych danych, takich jak hasła lub dużych plików z repo Git, więc ma prostą flagę, która usunie wszelkie duże historyczne (nie-in-your-current-commit) pliki: „--strip-blobs- większy niż'
$ java -jar bfg.jar --strip-blobs-bigger-than 100M
Jeśli chcesz określić pliki według nazwy, możesz to zrobić również:
$ java -jar bfg.jar --delete-files *.mp4
BFG jest 10-1000x szybszy niż gałąź filtru git i ogólnie znacznie łatwiejszy w użyciu - sprawdź pełne instrukcje użytkowania i przykłady, aby uzyskać więcej szczegółów.
Jeśli nie chcesz korzystać z CLI i pracujesz w systemie Windows, bardzo prostym rozwiązaniem jest użycie TortoiseGit , ma akcję „Usuń (zachowaj lokalną)” w menu, która działa dobrze.
Podobało mi się odpowiedź JonBrave'a, ale mam dość bałaganiarskich katalogów roboczych, które zatwierdzają - trochę mnie przeraża, więc oto co zrobiłem:
Cieszę się, że teraz to robi. Jednak OP pytał o to, by nie śledzić modyfikacji plików obecnych w .gitignore, a nie usuwanych plików wciąż pokazujących status.
Pamiętaj tylko, że niektóre z tych plików przechowują niektóre lokalne ustawienia użytkownika i preferencje dla projektów (np. Jakie pliki otworzyłeś). Tak więc za każdym razem, gdy nawigujesz lub zmieniasz IDE, plik ten jest zmieniany, a zatem sprawdza go i pokazuje, jak są niezatwierdzone zmiany.
Przyjęta odpowiedź nie powoduje, że Git „zapomina” o pliku ... ”(historycznie). Powoduje to, że git ignoruje plik w teraźniejszości / przyszłości.
Ta metoda powoduje, że git całkowicie zapomina zignorowane pliki ( przeszłość / teraźniejszość / przyszłość), ale nie robi tego usuwa niczego z katalogu roboczego (nawet po ponownym pobraniu ze zdalnego).
Metoda ta wymaga wykorzystania /.git/info/exclude(preferowane) lub wcześniej istniejących.gitignore w każdym z zatwierdzeń, które pliki mają być ignorowane / zapomniane. 1
Wszystkie metody wymuszania git ignorują zachowanie po fakcie skutecznie ponownie zapisują historię, a zatem mają znaczące konsekwencje dla publicznych / wspólnych / wspólnych repozytoriów, które mogą zostać wyciągnięte po tym procesie. 2)
Porady ogólne: zacznij od czystego repozytorium - wszystko zostało popełnione, nic nie czeka w katalogu roboczym lub indeksie i wykonaj kopię zapasową !
#commit up-to-date .gitignore (if not already existing)#this command must be run on each branch
git add .gitignore
git commit -m "Create .gitignore"#apply standard git ignore behavior only to current index, not working directory (--cached)#if this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist#this command must be run on each branch
git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached
#Commit to prevent working directory data loss!#this commit will be automatically deleted by the --prune-empty flag in the following command#this command must be run on each branch
git commit -m "ignored index"#Apply standard git ignore behavior RETROACTIVELY to all commits from all branches (--all)#This step WILL delete ignored files from working directory UNLESS they have been dereferenced from the index by the commit above#This step will also delete any "empty" commits. If deliberate "empty" commits should be kept, remove --prune-empty and instead run git reset HEAD^ immediately after this command
git filter-branch --tree-filter 'git ls-files -z --ignored --exclude-standard | xargs -0 git rm -f --ignore-unmatch'--prune-empty --tag-name-filter cat ----all
#List all still-existing files that are now ignored properly#if this command returns nothing, it's time to restore from backup and start over#this command must be run on each branch
git ls-files --other --ignored --exclude-standard
Na koniec postępuj zgodnie z resztą tego przewodnika GitHub (zaczynając od kroku 6), który zawiera ważne ostrzeżenia / informacje o poniższych poleceniach .
Inni deweloperzy, którzy pobierają teraz zmodyfikowane zdalne repozytorium, powinni wykonać kopię zapasową, a następnie:
#fetch modified remote
git fetch --all
#"Pull" changes WITHOUT deleting newly-ignored files from working directory#This will overwrite local tracked files with remote - ensure any local modifications are backed-up/stashed
git reset FETCH_HEAD
Przypisy
1 Ponieważ /.git/info/excludemożna zastosować do wszystkich historycznych zatwierdzeń przy użyciu powyższych instrukcji, być może szczegóły dotyczące umieszczania .gitignorepliku w historycznych zatwierdzeniach, które go potrzebują, wykraczają poza zakres tej odpowiedzi. Chciałem, żeby właściwość .gitignoreznajdowała się w głównym zatwierdzeniu, jakby to była pierwsza rzecz, którą zrobiłem. Inni mogą się tym nie przejmować, ponieważ /.git/info/excludemogą osiągnąć to samo, bez względu na to, gdzie .gitignoreistnieje w historii zatwierdzeń, a wyraźne ponowne zapisanie historii jest bardzo drażliwym tematem, nawet jeśli zdaje sobie sprawę z konsekwencji .
FWIW, potencjalne metody mogą obejmować git rebaselub git filter-branchkopiowanie zewnętrznego.gitignore do każdego zatwierdzenia, podobnie jak odpowiedzi na to pytanie
2 Wymuszanie zachowania git ignore po fakcie przez zatwierdzenie wyników działania samodzielnego git rm --cachedpolecenia może spowodować usunięcie nowo zignorowanego pliku w przyszłych ściągnięciach ze zdalnego sterowania wymuszonego. --prune-emptyFlag w następującej git filter-branchkomendy pozwala uniknąć tego problemu poprzez automatyczne usunięcie poprzedniego „usunąć wszystkie pliki ignorowane” indeksu tylko popełnić. Ponowne pisanie historii gitów zmienia także skróty zatwierdzania, które sieją spustoszenie w przyszłych ściągnięciach z repozytoriów publicznych / wspólnych / współpracujących. Proszę zrozumieć konsekwencje w pełni przed zrobieniem tego do takiego repozytorium. W tym przewodniku GitHub określono:
Powiedz swoim współpracownikom, aby utworzyli bazy , a nie scalali, wszelkie gałęzie, które utworzyli ze starej (skażonej) historii repozytorium. Jedno zatwierdzenie scalania może przywrócić część lub całą skażoną historię, którą właśnie zadałeś sobie trud oczyszczenia.
Alternatywnymi rozwiązaniami, które nie wpływają na zdalne repo, są git update-index --assume-unchanged </path/file>lub git update-index --skip-worktree <file>, których przykłady można znaleźć tutaj .
W moim przypadku miałem kilka plików .lock w kilku katalogach, które musiałem usunąć. Uruchomiłem następujące i działało bez konieczności wchodzenia do każdego katalogu, aby je usunąć:
git rm -r --cached **/*.lock
W ten sposób wszedłem do każdego folderu w „katalogu głównym”, w którym byłem, i wykluczyłem wszystkie pliki, które pasowały do wzorca.
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, które nie podąży niewłaściwą drogą.git update-index --assume-unchanged
. To rozwiązanie 1) utrzymuje plik na serwerze (indeks), 2) pozwala swobodnie go modyfikować lokalnie.--skip-worktree
, patrz: stackoverflow.com/questions/13630849/...git update-index --assume-unchanged <file>
jest poprawny, a plik pozostanie w repozytorium, a zmiany nie zostaną dodanegit add
. Jeśli NIE (na przykład był to jakiś plik pamięci podręcznej, wygenerowany plik itp.),git rm --cached <file>
Usunie go z repozytorium.--assume-unchanged
kwestii wydajności, aby git nie sprawdzał statusu dużych śledzonych plików, ale preferuje--skip-worktree
to, co dotyczy zmodyfikowanych plików śledzonych, których użytkownik nie chce już zatwierdzać. Zobacz stackoverflow.com/questions/13630849/...Odpowiedzi:
.gitignore
zapobiegnie dodawaniu nieśledzonych plików (bezadd -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.
Jeśli chcesz usunąć cały folder, musisz usunąć z niego wszystkie pliki rekurencyjnie.
Usunięcie pliku z rewizji głównej nastąpi przy następnym zatwierdzeniu.
OSTRZEŻENIE: Chociaż nie usunie to fizycznego pliku z twojego lokalnego, usunie pliki z innych komputerów programistów na następnym
git pull
.źródło
git add .
zostanie dodany do indeksu. A następne zatwierdzenie zatwierdziłoby to do repozytorium. Aby tego uniknąć, zaraz po tym wszystkim mataal powiedział jeszcze jedno polecenie:git update-index --assume-unchanged <path&filename>
git rm -r -q --cached .
git pull
.Poniższa seria poleceń usunie wszystkie elementy z Git Index (nie z katalogu roboczego lub lokalnego repozytorium), a następnie zaktualizuje Git Index, przestrzegając ignorowania git. PS. Indeks = pamięć podręczna
Pierwszy:
Następnie:
Lub jednowarstwowy:
źródło
git pull
.git rmignored
..gitignore
. Które może być trudne do ustalenia, jeśli zależy od tego, jaki hałasgit status
występuje po tym poleceniu. Polecenie, które usuwa tylko nowo zignorowane pliki, byłoby lepsze. Dlatego wolę odpowiedźgit update-index wykonuje dla mnie zadanie:
Uwaga: To rozwiązanie jest w rzeczywistości niezależne,
.gitignore
ponieważ gitignore jest przeznaczony tylko dla nieśledzonych plików.edycja: Od czasu opublikowania tej odpowiedzi utworzono nową opcję, którą należy preferować. Powinieneś użyć tego,
--skip-worktree
co jest dla zmodyfikowanych plików śledzonych, których użytkownik nie chce już zatwierdzać i zachować--assume-unchanged
wydajność, aby git nie sprawdzał statusu dużych plików śledzonych. Zobacz szczegóły na https://stackoverflow.com/a/13631525/717372 ...źródło
git status
i jest bardzo intuicyjne. Dzięki.rm [...] .
rozwiązania, ponieważ przynajmniej mogłem sobie wyobrazić, jak to działa. Nie znalazłem świetnej dokumentacji na temat tego, coupdate-index
i--assume-unchanged
robię. Czy ktoś może dodać, jak to się ma do innych, ponieważ chciałbym usunąć wszystkie pliki, które zostałyby zignorowane? (Lub link do jasnego wyjaśnienia?)git update-index --assume-unchanged <path> …
spowoduje, że git zignoruje zmiany w określonych ścieżkach, niezależnie od.gitignore
. Jeśli pobierzesz z pilota, a ten pilot ma zmiany w tej ścieżce, git nie powiedzie scalenia 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.gitignore
, zobaczysz ją w przyszłościgit status
. Pierwsza opcja ma mniej hałasu w historii zatwierdzeń git i pozwala na rozpowszechnianie zmian w pliku „ignorowanym” w przyszłości.Spowoduje to pobranie listy zignorowanych plików i usunięcie ich z indeksu, a następnie zatwierdzenie zmian.
źródło
git ls-files --ignored --exclude-standard | xargs git rm
. Wierzę, że ta odpowiedź jest najlepsza! Ponieważ jest to bardzo jasne, w stylu uniksowym i robi pożądaną rzecz w bezpośredni sposób, bez komponowania skutków ubocznych innych, bardziej złożonych poleceń.git rm
narzeka, jeślils-files
nic nie pasuje. Służyxargs -r git rm ...
do informowania, abyxargs
nie uruchamiać,git rm
jeśli nie pasują żadne pliki.git ls-files --ignored --exclude-standard -z|xargs -0 git rm --cached
Zawsze używam tego polecenia, aby usunąć te nieśledzone pliki. Jednoliniowy, uniksowy styl, czyste wyjście:
Zawiera listę wszystkich zignorowanych plików, zamiast tego zastępuje każdą linię wyjściową linią cytowaną, aby obsługiwać ścieżki ze spacjami w środku, i przekazuje wszystko,
git rm -r --cached
aby usunąć ścieżki / pliki / katalogi z indeksu.źródło
git ls-files --ignored --exclude-standard
pozwala najpierw zrozumieć / zweryfikować, jakie pliki.gitignore
zostaną wykluczone / usunięte przez nowy , zanim przejdziesz dalej i wykonasz finałgit rm
.\n
. Zamieściłem moje rozwiązanie, aby to zrobić.sed: 1: "s/.*/": unterminated substitute in regular expression
w poleceniu filter-branch na repozytorium ze spacjami. (Wydaje się, że działa poza gałęzią filtrów). Kiedyśgit ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached
z @ JonBrave za odpowiedź zamiast.przenieś to, zatwierdz, a następnie przenieś z powrotem. To działało dla mnie w przeszłości. Prawdopodobnie istnieje bardziej „bardziej gitarzysta” sposób na osiągnięcie tego.
źródło
Jeśli nie możesz
git rm
śledzić pliku, ponieważ inne osoby mogą go potrzebować (ostrzeżenie, nawet jeśli Tygit rm --cached
, gdy ktoś inny dostanie tę zmianę, jego pliki zostaną usunięte w systemie plików). Często są one wykonywane z powodu nadpisywania plików konfiguracyjnych, poświadczeń uwierzytelnienia itp. Informacje na temat sposobów obejścia problemu można znaleźć na stronie https://gist.github.com/1423106 .Podsumowując:
źródło
git checkout <oldref> -- <filename>
- ale wtedy zostanie sprawdzone i zignorowane.--assume-unchanged
): albo jest to kult ładunku i powinien zostać odrzucony, albo możesz wyjaśnić, dlaczego (o czym jestem przekonany) i stanie się przydatny.Użyj tego, gdy:
1. Chcesz wyśledzić wiele plików lub
2. Zaktualizowałeś plik gitignore
Załóżmy, że już dodałeś / zatwierdziłeś niektóre pliki do swojego repozytorium git, a następnie dodajesz je do swojego .gitignore; pliki te będą nadal obecne w indeksie repozytorium. W tym artykule zobaczymy, jak się ich pozbyć.
Krok 1: Zatwierdź wszystkie zmiany
Przed kontynuowaniem upewnij się, że wszystkie zmiany zostały zatwierdzone, w tym plik .gitignore.
Krok 2: Usuń wszystko z repozytorium
Aby wyczyścić repozytorium, użyj:
rm
Komenda może być pamiętliwy. Jeśli chcesz spróbować tego, co robi wcześniej, dodaj flagę-n
lub,--dry-run
aby to sprawdzić.Krok 3: Dodaj wszystko ponownie
Krok 4: Zatwierdź
Twoje repozytorium jest czyste :)
Wciśnij zmiany na pilocie, aby zobaczyć, że zmiany również tam obowiązują.
źródło
Osiągnąłem to za pomocą git filter-branch . Dokładne polecenie, którego użyłem, pochodzi ze strony podręcznika:
OSTRZEŻENIE : spowoduje to usunięcie pliku z całej historii
To polecenie odtworzy całą historię zatwierdzeń, wykonując
git rm
przed każdym zatwierdzeniem, a zatem usunie określony plik. Nie zapomnij wykonać kopii zapasowej przed uruchomieniem polecenia, ponieważ zostanie utracone.źródło
Co mi nie zadziałało
(Pod Linuksem) chciałem użyć tutaj postów sugerujących takie
ls-files --ignored --exclude-standard | xargs git rm -r --cached
podejście. Jednak (niektóre) pliki, które mają zostać usunięte, miały osadzoną nową linię / LF /\n
w swoich nazwach. Żadne z rozwiązań:poradzić sobie z tą sytuacją (otrzymuj błędy dotyczące plików nie znaleziono)
Więc oferuję
Używa
-z
argumentu do plików ls , a-0
argumentu do xargs, aby bezpiecznie / poprawnie zaspokoić „nieprzyjemne” znaki w nazwach plików.Na stronie podręcznika git-ls-files (1) stwierdza:
więc myślę, że moje rozwiązanie jest potrzebne, jeśli w nazwach plików znajduje się którykolwiek z tych znaków.
źródło
git add .
. Zawiera także najlepsze ulepszenia z niektórych powyższych komentarzy.git commit -am "Remove ignored files"
później thSoft do swojej odpowiedzi? Twoje odpowiedzi razem pomogły mi przejść przez: jgit commit -a
. Dla mniegit rm --cached
wpływa dokładnie na indeks, więc nie ma potrzeby ustawiania plików po ...Zaktualizuj
.gitignore
plik - na przykład dodaj folder, którego nie chcesz śledzić.gitignore
.git rm -r --cached .
- Usuń wszystkie śledzone pliki, w tym poszukiwane i niepożądane. Twój kod będzie bezpieczny, dopóki zapisałeś go lokalnie.git add .
- Wszystkie pliki zostaną dodane z powrotem, z wyjątkiem tych w.gitignore
.Czapka dla @AkiraYamamoto za wskazanie nam właściwego kierunku.
źródło
Myślę, że może git nie może całkowicie zapomnieć o pliku z powodu jego koncepcji ( sekcja „Migawki, nie różnice” ).
Ten problem nie występuje na przykład podczas korzystania z CVS. CVS przechowuje informacje jako listę zmian opartych na plikach. Informacje dla CVS to zestaw plików i zmiany wprowadzane w każdym pliku w czasie.
Ale w Git za każdym razem, gdy zatwierdzasz lub zapisujesz stan swojego projektu, zasadniczo robi zdjęcie, jak wyglądają wszystkie twoje pliki w tym momencie i przechowuje odniesienie do tej migawki. Tak więc, jeśli dodałeś plik raz, zawsze będzie on obecny w tej migawce.
Te 2 artykuły były dla mnie pomocne:
git zakłada-niezmieniony vs. pomiń-roboczy i jak ignorować zmiany w śledzonych plikach za pomocą Git
Na tej podstawie wykonuję następujące czynności, jeśli plik jest już śledzony:
Od tego momentu wszystkie lokalne zmiany w tym pliku będą ignorowane i nie będą przekazywane zdalnie. Jeśli plik zostanie zmieniony zdalnie, nastąpi konflikt, kiedy
git pull
. Skrytka nie będzie działać. Aby rozwiązać ten problem, skopiuj zawartość pliku w bezpieczne miejsce i wykonaj następujące kroki:Zawartość pliku zostanie zastąpiona treścią zdalną. Wklej zmiany z bezpiecznego miejsca do pliku i wykonaj ponownie:
Jeśli wszyscy, którzy pracują z projektem, wykonają
git update-index --skip-worktree <file>
, problemypull
powinny być nieobecne. To rozwiązanie jest odpowiednie dla plików konfiguracyjnych, gdy każdy programista ma własną konfigurację projektu.Nie jest to wygodne za każdym razem, gdy plik jest zmieniany na pilocie, ale może chronić go przed nadpisaniem przez zawartość zdalną.
źródło
Wykonaj kolejno następujące kroki, wszystko będzie dobrze.
1. usuń błędnie dodane pliki z katalogu / magazynu . Możesz użyć polecenia „rm -r” (dla systemu Linux) lub usunąć je, przeglądając katalogi. Lub przenieś je w inne miejsce na komputerze. [Może być konieczne zamknięcie IDE, jeśli uruchamiasz w celu przeniesienia / usunięcia ]
2. dodaj pliki / katalogi do
gitignore
pliku teraz i zapisz go.3. teraz usuń je z pamięci podręcznej git za pomocą tych poleceń (jeśli istnieje więcej niż jeden katalog, usuń je jeden po drugim, powtarzając to polecenie)
4.Now zrobić popełnić i Push , użyj tych poleceń. Spowoduje to usunięcie tych plików ze zdalnego programu git i spowoduje, że git przestanie śledzić te pliki.
źródło
Odpowiedź kopiuj / wklej to
git rm --cached -r .; git add .; git status
To polecenie zignoruje pliki, które zostały już zatwierdzone w repozytorium Git, ale teraz je dodaliśmy
.gitignore
.źródło
Odpowiedź Matta Feara była najskuteczniejsza IMHO. Poniżej znajduje się tylko skrypt PowerShell dla tych w systemie Windows, aby usuwać tylko pliki z repozytorium git, które pasują do ich listy wykluczeń.
źródło
Przenieś lub skopiuj plik w bezpieczne miejsce, aby go nie zgubić. Następnie uruchom plik i zatwierdź. Plik będzie nadal wyświetlany, jeśli powrócisz do jednego z wcześniejszych zatwierdzeń lub do innej gałęzi, w której nie został usunięty. Jednak we wszystkich przyszłych zatwierdzeniach plik nie będzie ponownie wyświetlany. Jeśli plik znajduje się w git ignoruj, możesz przenieść go z powrotem do folderu, a git go nie zobaczy.
źródło
git rm --cached
usunie plik z indeksu bez usuwania go z dysku, więc nie trzeba go przenosić / kopiowaćUżycie
git rm --cached
polecenia nie odpowiada na pierwotne pytanie:W rzeczywistości, to rozwiązanie spowoduje, że plik do usuniętego w każdym innym przypadku repozytorium podczas wykonywania
git pull
!Prawidłowy sposób zmuszenia gita do zapomnienia o pliku jest udokumentowany przez GitHub tutaj .
Polecam lekturę dokumentacji, ale w zasadzie:
po prostu zastąp
full/path/to/file
pełną ścieżką do pliku. Upewnij się, że dodałeś plik do swojego.gitignore
.Będziesz także musiał (tymczasowo) zezwolić na wypychanie do repozytorium bez szybkiego przewijania do przodu , ponieważ zmieniasz historię git.
źródło
BFG został zaprojektowany specjalnie do usuwania niechcianych danych, takich jak hasła lub dużych plików z repo Git, więc ma prostą flagę, która usunie wszelkie duże historyczne (nie-in-your-current-commit) pliki: „--strip-blobs- większy niż'
Jeśli chcesz określić pliki według nazwy, możesz to zrobić również:
BFG jest 10-1000x szybszy niż gałąź filtru git i ogólnie znacznie łatwiejszy w użyciu - sprawdź pełne instrukcje użytkowania i przykłady, aby uzyskać więcej szczegółów.
Źródło: https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html
źródło
Jeśli nie chcesz korzystać z CLI i pracujesz w systemie Windows, bardzo prostym rozwiązaniem jest użycie TortoiseGit , ma akcję „Usuń (zachowaj lokalną)” w menu, która działa dobrze.
źródło
Podobało mi się odpowiedź JonBrave'a, ale mam dość bałaganiarskich katalogów roboczych, które zatwierdzają - trochę mnie przeraża, więc oto co zrobiłem:
git config --global alias.exclude-ignored '! git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached && git ls-files -z --ignored --exclude-standard | xargs -0 git stage && git stage .gitignore && git commit -m "nowy gitignore i usuń zignorowane pliki z indeksu"
rozbicie go:
źródło
Nie jest to już problemem w najnowszym git (v2.17.1 w momencie pisania).
.gitignore
Wreszcie ignoruje śledzone, ale usuniętych plików. Możesz to sprawdzić samodzielnie, uruchamiając następujący skrypt. Ostatecznegit status
oświadczenie powinno zawierać „nic do popełnienia”.źródło
W przypadku już popełnionego
DS_Store
:Zignoruj je przez:
Wreszcie dokonaj zatwierdzenia!
źródło
Szczególnie w przypadku plików opartych na IDE używam tego:
Na przykład slnx.sqlite, właśnie się go pozbyłem, jak poniżej:
Pamiętaj tylko, że niektóre z tych plików przechowują niektóre lokalne ustawienia użytkownika i preferencje dla projektów (np. Jakie pliki otworzyłeś). Tak więc za każdym razem, gdy nawigujesz lub zmieniasz IDE, plik ten jest zmieniany, a zatem sprawdza go i pokazuje, jak są niezatwierdzone zmiany.
źródło
Na koniec postępuj zgodnie z resztą tego przewodnika GitHub (zaczynając od kroku 6), który zawiera ważne ostrzeżenia / informacje o poniższych poleceniach .
Inni deweloperzy, którzy pobierają teraz zmodyfikowane zdalne repozytorium, powinni wykonać kopię zapasową, a następnie:
Przypisy
1 Ponieważ
/.git/info/exclude
można zastosować do wszystkich historycznych zatwierdzeń przy użyciu powyższych instrukcji, być może szczegóły dotyczące umieszczania.gitignore
pliku w historycznych zatwierdzeniach, które go potrzebują, wykraczają poza zakres tej odpowiedzi. Chciałem, żeby właściwość.gitignore
znajdowała się w głównym zatwierdzeniu, jakby to była pierwsza rzecz, którą zrobiłem. Inni mogą się tym nie przejmować, ponieważ/.git/info/exclude
mogą osiągnąć to samo, bez względu na to, gdzie.gitignore
istnieje w historii zatwierdzeń, a wyraźne ponowne zapisanie historii jest bardzo drażliwym tematem, nawet jeśli zdaje sobie sprawę z konsekwencji .FWIW, potencjalne metody mogą obejmować
git rebase
lubgit filter-branch
kopiowanie zewnętrznego.gitignore
do każdego zatwierdzenia, podobnie jak odpowiedzi na to pytanie2 Wymuszanie zachowania git ignore po fakcie przez zatwierdzenie wyników działania samodzielnego
git rm --cached
polecenia może spowodować usunięcie nowo zignorowanego pliku w przyszłych ściągnięciach ze zdalnego sterowania wymuszonego.--prune-empty
Flag w następującejgit filter-branch
komendy pozwala uniknąć tego problemu poprzez automatyczne usunięcie poprzedniego „usunąć wszystkie pliki ignorowane” indeksu tylko popełnić. Ponowne pisanie historii gitów zmienia także skróty zatwierdzania, które sieją spustoszenie w przyszłych ściągnięciach z repozytoriów publicznych / wspólnych / współpracujących. Proszę zrozumieć konsekwencje w pełni przed zrobieniem tego do takiego repozytorium. W tym przewodniku GitHub określono:Alternatywnymi rozwiązaniami, które nie wpływają na zdalne repo, są
git update-index --assume-unchanged </path/file>
lubgit update-index --skip-worktree <file>
, których przykłady można znaleźć tutaj .źródło
Jeśli ktoś ma problemy z systemem Windows i chcesz zignorować cały folder, „cd”, aby wybrać „folder” i wykonaj „Git Bash Here”.
źródło
W moim przypadku miałem kilka plików .lock w kilku katalogach, które musiałem usunąć. Uruchomiłem następujące i działało bez konieczności wchodzenia do każdego katalogu, aby je usunąć:
W ten sposób wszedłem do każdego folderu w „katalogu głównym”, w którym byłem, i wykluczyłem wszystkie pliki, które pasowały do wzorca.
Mam nadzieję, że to pomaga innym!
źródło