Jak sprawić, by Git "zapomnieć" o pliku, który został tropi, ale teraz jest.гитюдного?

masz plik, który jest monitorowany git, ale teraz plik znajduje się na .gitignore lista.

jednak plik ten jest w dalszym ciągu w git status po edycji. Jak można zmuszać git całkowicie o tym zapomnieć?


.gitignore pozwoli zapobiec nienamierzalne pliki mogą być dodawane (bez add -f) do zestawu plików, monitorowanych git, jednak git będzie nadal śledzić wszystkie pliki, które już są śledzone.

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

git rm --cached <file>

usuwanie pliku z wersji head nastąpi podczas następnego zatwierdzenia.


seria poleceń poniżej usuwa wszystkie elementy z indeksu Git (nie z katalogu roboczego lub lokalnego REPO), a następnie aktualizuje indeks Git, przy zachowaniu git ignoruje. PS. Index = Cache

pierwszy:

git rm -r --cached . 
git add .

następnie:

git commit -am "Remove ignored files"

git update-index robi robotę za mnie:

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

Uwaga: to rozwiązanie praktycznie nie zależy od .gitignore ponieważ gitignore jest przeznaczony tylko dla неотслеживаемых plików.

edit: ponieważ ta odpowiedź została opublikowana, powstała nowa opcja, i to musi być uprzywilejowany. Musisz użyć --skip-worktree który jest przeznaczony do zmienionych śledzonych plików, które użytkownik już nie chce rejestrować i przechowywać --assume-unchanged do wykonania, aby zapobiec git w celu sprawdzenia stanu dużych śledzonych plików. Cm.https://stackoverflow.com/a/13631525/717372 w celu uzyskania bardziej szczegółowych informacji...


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

To bierze lista ignorowanych plików i usuwa je z indeksu, a następnie wprowadzane zmiany.


Ja zawsze używam tego polecenia w celu usunięcia tych неотслеженных plików. Jednoliniowy, Unix-styl, czysty wniosek:

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

wymienia wszystkie swoje zignorowane pliki, zastępuje każdą wyjściową wiersz цитируемой paskiem zamiast przetwarzać drodze ze spacjami wewnątrz i wysyłać wszystko w git rm -r --cached aby usunąć ścieżek / plików / dir z indeksu.


Jeśli nie możesz git rm śledzony plik, bo może się przydać innym ludziom (ostrzeżenie, nawet jeśli git rm --cached, gdy ktoś inny dostaje to zmiana, ich pliki zostaną usunięte w ich systemie). To jest często wykonywana z powodu zastąpienia pliku konfiguracyjnego, poświadczeń uwierzytelniania itp. Proszę spojrzeć nahttps://gist.github.com/1423106 dla sposobów ludzie pracowali wokół problemu.

podsumowując:

  • twój aplikacji do ignorowanych plików konfiguracyjnych-najwyższą.ini i korzystać z bardziej zaawansowanych plik config.ini (lub alternatywnie poszukaj~/.config / myapp.ini, lub $MYCONFIGFILE)
  • zablokować plik config-sample.ini i ignorować plik config.ini, mieć skrypt lub podobną kopię pliku w razie potrzeby, jeśli jest to konieczne.
  • spróbuj użyć gitattributes clean/rozmazywanie magic, aby zastosować i usunąć zmiany dla ciebie, na przykład, posmarować plik konfiguracyjny jako kontroli z alternatywnej gałęzi i wyczyścić plik konfiguracyjny jak sprawdzanie od głowy. To trudny materiał, nie polecam go dla początkującego użytkownika.
  • zapisz plik konfiguracji w gałęzi wdrażania, poświęconej mu, że nigdy nie jest łączony z master. Gdy chcesz rozwinąć / skompilować / przetestować, łączą się z tą gałęzią i bezpłatne ten plik. To, w rzeczywistości, podejście rozmazywanie / clean, za wyjątkiem korzystania z zasad scalania ludzi i modułów extra-git.
  • Anti-recommentation: nie używaj assume-unchanged, że skończy się tylko łzami.

przesuń go, zablokować, a następnie przenieść go z powrotem. W przeszłości działało. Prawdopodobnie jest bardziej "sprytny" sposób to osiągnąć.


co nie zadziałało dla mnie

(pod Linux), chciałem użyć wiadomości tutaj, oferując ls-files --ignored --exclude-standard | xargs git rm -r --cached podejście. Jednak (niektóre) te pliki miały wbudowaną nową linię/LF/\n w ich nazwy. Ani jedno 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ą (bezpłatne błędy o plikach nie znalazłem).

dlatego proponuję

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

używa ls-files a


zrobiłem to za pomocą git filter-branch. Dokładna zespół, który kiedyś został zaczerpnięty z strony man:

ostrzeżenie: to usunie plik z całej swojej historii

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

ta drużyna będzie odtworzyć całą historię zatwierdzenia, wykonując git rm przed każdą blokadą i tak odciąć się od podanego pliku. Nie zapomnij, aby utworzyć kopię zapasową przed uruchomieniem polecenia jak to zostaną utracone.


używać, gdy:

1. Chcesz, aby śledzić wiele plików, lub

2. Masz zaktualizowany plik. gitignore

link do źródła: http://www.codeblocq.com/2016/01/Untrack-files-already-added-to-git-repository-based-on-gitignore/

załóżmy, że masz już dodane/zanotowali niektóre pliki w swoim repozytorium git, a następnie dodaje je do swojego .gitignore; pliki te nadal będą uczestniczyć w twój indeks magazynu. W tym artykule zobaczymy, jak się ich pozbyć.

Krok 1: zablokować wszystkie swoje zmiany

zanim przejdziesz dalej, upewnij się, że wszystkie zmiany są zablokowane, w tym twoje .plik.gitignore

Krok 2: Usuń wszystkie z repozytorium

aby wyczyścić REPO, należy użyć:

git rm -r --cached .
  • rm jest zespołem remove
  • - r pozwoli rekursywny usuwanie
  • –zapisana usuwa tylko pliki z indeksu. Pliki nadal tam będą.

rm zespół może być nieubłagany. Jeśli chcesz spróbować, co on robi z góry, dodaj -n lub --dry-run flaga, aby sprawdzić rzeczy.

Krok 3: Re dodać wszystkie

git add .

Krok 4: Commit

git commit -m ".gitignore fix"

repozytorium czyste :)

kliknij zmian na pilocie zdalnego sterowania, aby zobaczyć zmiany są skuteczne i tam.


  1. aktualizuj .gitignore file-na przykład, dodaj folder, który chcesz śledzić w .gitignore.

  2. git rm -r --cached . - usunąć wszystkie monitorowane pliki, w tym poszukiwanych i niechciane. Twój kod będzie bezpieczny, gdy jesteś zapisany lokalnie.

  3. git add . wszystkie pliki zostaną dodane z powrotem, z wyjątkiem .gitignore.


końcówka kapelusze @AkiraYamamoto, aby wskazać nam w dobrym kierunku.


myślę, że, być może, git nie może całkowicie zapomnieć o pliku z powodu jego koncepcji (sekcja "zdjęcia, a nie różnice").

ten problem nie występuje, na przykład, podczas korzystania z CVS. CVS przechowuje informacje w postaci listy zmian na podstawie plików. Informacje dla CVS jest zestaw plików i zmian wprowadzonych w każdy plik z upływem czasu.

ale w Git za każdym razem, kiedy dokonujesz lub zapisujesz stan swojego projektu, to w zasadzie sprawia, że obraz tego, co wszystkie pliki wyglądać w tym momencie i zapisuje link do tego zdjęcia. Tak więc, jeśli dodasz plik raz, zawsze będzie obecny w tym zdjęciu.

te 2 artykuły były pomocne dla mnie:

git załóżmy-bez zmian vs skip-worktree i jak ignorować zmian w monitorowanych plikach z Git

opierając się na tym, robię następne, jeśli plik już jest śledzony:

git update-index --skip-worktree <file>

od w tym momencie wszystkie lokalne zmiany w tym pliku są ignorowane i nie przejdą na zdalny. Jeśli plik zostanie zmieniony na zdalnym, konflikt się stanie, gdy git pull. Сташ nie działa. Aby go rozwiązać,kopiuj zawartość pliku w bezpieczne miejsce i wykonaj następujące czynności:

git update-index --no-skip-worktree <file>
git stash
git pull 

zawartość pliku zostanie zastąpione zawartością zdalną. Włóż zmiany z bezpiecznego miejsca w plik i wykonaj jeszcze raz:

git update-index --skip-worktree <file>

jeśli każdy, kto pracuje z projektem, będzie wykonywać git update-index --skip-worktree <file>, problemy z pull musi być. To rozwiązanie nadaje się do plików konfiguracji, gdy każdy twórca ma swoją własną konfigurację projektu.

to nie jest bardzo łatwe do zrobienia za każdym razem, gdy plik został zmieniony na zdalnym, ale może go chronić przed zastąpieniem zdalnym treścią.


przenieść lub skopiować plik w bezpiecznym miejscu, tak, że nie stracisz go. Następnie git rm plik i trwałość. Plik nadal będzie wyświetlany, jeśli wrócisz do jednego z poprzednich commits lub inny oddział, gdzie nie został usunięty. Jednak we wszystkich przyszłych коммитах nie zobaczysz plik. Jeśli plik znajduje się w Git ignore, można przenieść go z powrotem do folderu, i git go nie zobaczy.


odpowiedź od Matta strachu był najbardziej skuteczny IMHO. Poniżej znajduje się tylko skrypt PowerShell dla tych, którzy w systemie windows, aby usunąć tylko pliki z repozytorium git, który odpowiada ich listy wyjątków.

# Get files matching exclusionsfrom .gitignore
# Excluding comments and empty lines
$ignoreFiles =  gc .gitignore | ?{$_ -notmatch  "#"} |  ?{$_ -match  "\S"} | % {
                    $ignore = "*" + $_ + "*"
                    (gci -r -i $ignore).FullName
                }
$ignoreFiles = $ignoreFiles| ?{$_ -match  "\S"}

# Remove each of these file from Git 
$ignoreFiles | % { git rm $_}

git add .

BFG specjalnie zaprojektowany do usuwania niechcianych danych, takich jak duże pliki lub hasła z repozytoriów Git, więc ma prosty flaga, który usunie wszelkie wielkie historyczne (nie w bieżącej zatwierdzenia) pliki: '--strip-blobs-bigger-than'

$ java -jar bfg.jar --strip-blobs-bigger-than 100M

Jeśli chcesz określić pliki według nazwy, można również zrobić to:

$ java -jar bfg.jar --delete-files *.mp4

BFG 10-1000x szybciej, niż git filter-branch, i, jak zwykle, dużo łatwiejsze w obsłudze-sprawdź pełne wykorzystanie instrukcje a przykłady aby uzyskać więcej informacji.

źródło: https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html


Jeśli nie chcesz korzystać z CLI i pracujesz w systemie Windows, bardzo proste rozwiązanie-użyć TortoiseGit, ma działanie usuń (zapisz lokalny) " w menu, które działa świetnie.


spodobała Mi się odpowiedź JonBrave, ale mam dość brudne robocze katalogi, które mnie trochę przerażają, więc oto co zrobiłem:

git config --global alias.wykluczyć-ignorować!PIP HP-pliki -h --ignoruj --wykluczyć-standard | polecenia xargs -0 PIP RM -R --buforowane && Git w HP-pliki -h --ignoruj --wykluczyć-standard | polecenia xargs -0 PIP etap && Git na scenie .gitignore & & git commit-m "utwórz gitignore i usunąć pliki ignorowane z indeksu"'

puzzle go w dół:

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 "new gitignore and remove ignored files from index"
  • usuń pliki ignorowane z index
  • etap .gitignore i pliki, które dopiero co usunięto
  • commit

To już nie problem, w ostatnim git (v2.17.1 w chwili pisania artykułu).

.gitignore w końcu ignoruje śledzone, ale usunięte pliki. Możesz to sprawdzić samodzielnie, wykonując następujący scenariusz. Finał git status operator musi poinformować "nic nie przymocować".

# Create empty repo
mkdir gitignore-test
cd gitignore-test
git init

# Create a file and commit it
echo "hello" > file
git add file
git commit -m initial

# Add the file to gitignore and commit
echo "file" > .gitignore
git add .gitignore
git commit -m gitignore

# Remove the file and commit
git rm file
git commit -m "removed file"

# Reintroduce the file and check status.
# .gitignore is now respected - status reports "nothing to commit".
echo "hello" > file
git status

W przypadku już doskonałego DS_Store:

find . -name .DS_Store -print0 | xargs -0 git rm --ignore-unmatch

ignoruj ich:

echo ".DS_Store" >> ~/.gitignore_global
echo "._.DS_Store" >> ~/.gitignore_global
echo "**/.DS_Store" >> ~/.gitignore_global
echo "**/._.DS_Store" >> ~/.gitignore_global
git config --global core.excludesfile ~/.gitignore_global

wreszcie, zrób blokadę!


wykonaj następujące kroki konsekwentnie, będzie w porządku.

1.usuń błędnie dodane pliki z książki telefonicznej/przechowywania. Możesz użyć polecenia rm-r"(dla linuksa) lub usunąć je, przeglądając katalogi.

2.dodaj pliki / katalogi w gitignore plik teraz i zapisz go.

3.teraz usuń z nich git cache Za pomocą tych poleceń (jeśli jest kilka katalogów, należy je usunąć jeden pojedynczo i wielokrotnie wydając to polecenie)

git rm -r --cached path-to-those-files

4.teraz do a commit i push użyj polecenia te. To będzie usuń te pliki z repozytorium git remote i zrobić git zatrzymaj śledzenie te pliki.

git add .
git commit -m "removed unnecessary files from git"
git push origin