Przypadkowo dodałem, zatwierdziłem i wrzuciłem ogromny plik binarny z moim najnowszym zatwierdzeniem do repozytorium Git.
Jak sprawić, by Git usunął obiekty, które zostały / zostały utworzone dla tego zatwierdzenia, aby mój .git
katalog ponownie się zmniejszył do rozsądnego rozmiaru?
Edycja : Dzięki za odpowiedzi; Wypróbowałem kilka rozwiązań. Żaden nie działał. Na przykład ten z GitHub usunął pliki z historii, ale .git
rozmiar katalogu się nie zmniejszył:
$ BADFILES=$(find test_data -type f -exec echo -n "'{}' " \;)
$ git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $BADFILES" HEAD
Rewrite 14ed3f41474f0a2f624a440e5a106c2768edb67b (66/66)
rm 'test_data/images/001.jpg'
[...snip...]
rm 'test_data/images/281.jpg'
Ref 'refs/heads/master' was rewritten
$ git log -p # looks nice
$ rm -rf .git/refs/original/
$ git reflog expire --all
$ git gc --aggressive --prune
Counting objects: 625, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (598/598), done.
Writing objects: 100% (625/625), done.
Total 625 (delta 351), reused 0 (delta 0)
$ du -hs .git
174M .git
$ # still 175 MB :-(
git-repack -a
po którym następujegit-prune-packed
na przykład. Zobacz blog.felipebalbi.com/2007/12/19/…filter-branch
,gc
,repack
, ...), nie, nie powinien zobaczyć każdy zły popełnić w ogóle. To znak, że sprzątanie nie odbyło się zgodnie z oczekiwaniami.Odpowiedzi:
Odpowiedziałem na to gdzie indziej i skopiuję tutaj, ponieważ jestem z tego dumny!
... i bez zbędnych ceregieli, przedstawię wam ten przydatny skrypt, git-gc-all, gwarantujący usunięcie wszystkich śmieci git, dopóki nie wymyślą dodatkowych zmiennych konfiguracyjnych:
git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 \ -c gc.rerereresolved=0 -c gc.rerereunresolved=0 \ -c gc.pruneExpire=now gc "$@"
Pomocna może być opcja --aggressive.
UWAGA: usunie to WSZYSTKIE rzeczy bez odniesień, więc nie przychodź do mnie płacz, jeśli później zdecydujesz, że chcesz zachować niektóre z nich!
Być może będziesz musiał najpierw uruchomić coś takiego, ojej, git jest skomplikowany !!
git remote rm origin rm -rf .git/refs/original/ .git/refs/remotes/ .git/*_HEAD .git/logs/ git for-each-ref --format="%(refname)" refs/original/ | xargs -n1 --no-run-if-empty git update-ref -d
Wszystko to umieściłem w scenariuszu, tutaj:
http://sam.nipl.net/b/git-gc-all-ferocious
źródło
xargs
polecenie powoduje błąd w systemie OS X z powodu nierozpoznanej opcji. Najprostsze rozwiązanie: zainstaluj GNU xargs przez homebrewbrew install findutils
i zamieńxargs
nagxargs
.Twoje
git reflog expire --all
jest nieprawidłowe. Usuwa wpisy reflog, które są starsze niż czas wygaśnięcia, który domyślnie wynosi 90 dni. Użyjgit reflog expire --all --expire=now
.Moja odpowiedź na podobne pytanie dotyczy problemu rzeczywistego usuwania nieużywanych obiektów z repozytorium.
źródło
1) Usuń plik z repozytorium git (a nie z systemu plików):
git rm --cached path/to/file
2) Zmniejsz repozytorium za pomocą:
git gc
,lub
git gc --aggressive
git prune
lub kombinacja powyższych, jak zasugerowano w tym pytaniu: Zmniejsz rozmiar repozytorium git
źródło
Ten przewodnik dotyczący usuwania danych wrażliwych może mieć zastosowanie przy użyciu tej samej metody. Będziesz przepisywać historię, aby usunąć ten plik z każdej wersji, w której był obecny. Jest to destrukcyjne i spowoduje konflikty repozytorium z innymi pobraniami, więc najpierw ostrzeż współpracowników.
Jeśli chcesz, aby plik binarny był dostępny w repozytorium dla innych osób, nie ma prawdziwego sposobu na robienie tego, co chcesz. Prawie wszystko albo nic.
źródło
Klucz dla mnie okazał się być uruchomiony,
git repack -A -d -f
a następniegit gc
zmniejszyć rozmiar pojedynczego pakietu git, który miałem.źródło
Hy!
Git otrzymuje tylko obiekty, których faktycznie potrzebuje podczas klonowania repozytoriów (jeśli dobrze to rozumiem)
Możesz więc zmienić ostatnie zatwierdzenie, usuwając plik dodany przez pomyłkę, a następnie przesłać zmiany do zdalnego repozytorium (z opcją -f, aby nadpisać również stare zatwierdzenie na serwerze)
Następnie, kiedy tworzysz nowy klon tego repozytorium, jego katalog .git powinien być tak mały, jak przed zatwierdzeniem dużego pliku (i).
Opcjonalnie, jeśli chcesz usunąć również niepotrzebne pliki z serwera, możesz usunąć repozytorium na serwerze i wypchnąć swoją nowo sklonowaną kopię (która ma pełną historię)
źródło
Zobacz „Usuwanie obiektów” w książce Pro Git:
http://git-scm.com/book/en/Git-Internals-Maintenance-and-Data-Recovery#Removing-Objects
Aktualizacja: zobacz także narzędzie do czyszczenia repozytoriów BFG: http://rtyley.github.io/bfg-repo-cleaner/
źródło
Pamiętaj, aby zmienić
Filename
na ten, który chcesz usunąć z repozytorium.źródło
W 2020 roku dokumentacja git-filter-branch odradza jego używanie i zaleca użycie alternatywy, takiej jak git-filter-repo . Może być również używany zamiast BFG .
Zauważ, że rozdział o przepisywaniu historii w księdze git nie został zaktualizowany. Nie ma również zalecenia GitHub dotyczącego usuwania poufnych danych.
źródło