145 mln = .git / objects / pack /
Napisałem skrypt, aby zsumować rozmiary różnic każdego zatwierdzenia i zatwierdzenia przed przejściem wstecz od końcówki każdej gałęzi. Otrzymuję 129 MB, czyli bez kompresji i bez uwzględniania tych samych plików we wszystkich oddziałach i wspólnej historii między oddziałami.
Git bierze to wszystko pod uwagę, więc spodziewałbym się dużo mniejszego repozytorium. Dlaczego więc .git jest taki duży?
Zrobiłem:
git fsck --full
git gc --prune=today --aggressive
git repack
Aby odpowiedzieć na pytanie, ile plików / zatwierdzeń, mam 19 gałęzi po około 40 plików w każdym. 287 zatwierdzeń, znalezionych przy użyciu:
git log --oneline --all|wc -l
Przechowywanie informacji o tym nie powinno zajmować 10 megabajtów.
git repack -a -d
zmniejszyłem moje repozytorium 956 MB do 250 MB . Wielkim sukcesem! Dzięki!Odpowiedzi:
Niedawno ściągnąłem złe repozytorium zdalne do lokalnego (
git remote add ...
igit remote update
). Po usunięciu niechcianego zdalnego odniesienia, gałęzi i tagów nadal miałem 1,4 GB (!) Zmarnowanego miejsca w moim repozytorium. Mogłem się tego pozbyć tylko klonując go za pomocągit clone file:///path/to/repository
. Zwróć uwagę,file://
że podczas klonowania lokalnego repozytorium ma to ogromne znaczenie - kopiowane są tylko obiekty, do których istnieją odwołania, a nie cała struktura katalogów.Edycja: Oto jedna linijka Iana do odtworzenia wszystkich gałęzi w nowym repozytorium:
źródło
Niektóre skrypty, których używam:
git-fatfiles
Jeśli chcesz więcej wierszy, zobacz także wersję Perla w sąsiedniej odpowiedzi: https://stackoverflow.com/a/45366030/266720
git-eradicate (for
video/parasite.avi
):Uwaga: drugi skrypt jest przeznaczony do całkowitego usunięcia informacji z Git (w tym wszystkich informacji z reflogów). Używaj ostrożnie.
źródło
git-fatfiles
skrypt ( ) pojawił się, gdy zadałem pytanie na IRC (Freenode / # git). Zapisałem najlepszą wersję do pliku, a następnie opublikowałem jako odpowiedź tutaj. (Nie mogę jednak oryginalnego autora w dziennikach IRC).git gc
już to robi,git repack
więc nie ma sensu ręcznie przepakowywać, chyba że masz zamiar przekazać mu jakieś specjalne opcje.Pierwszym krokiem jest sprawdzenie, czy większość miejsca zajmuje (jak w normalnym przypadku) baza danych obiektów.
Powinno to dać raport o tym, ile rozpakowanych obiektów jest w twoim repozytorium, ile zajmują miejsca, ile masz plików paczek i ile zajmują miejsca.
Idealnie byłoby, gdyby po przepakowaniu nie było żadnych rozpakowanych obiektów i jednego pliku pakietu, ale jest całkowicie normalne, że niektóre obiekty, do których nie odwołują się bezpośrednio bieżące gałęzie, są nadal obecne i rozpakowane.
Jeśli masz jedną dużą paczkę i chcesz wiedzieć, co zajmuje miejsce, możesz wyświetlić listę obiektów, które tworzą paczkę, wraz ze sposobem ich przechowywania.
Zauważ, że
verify-pack
pobiera plik indeksu, a nie sam plik pakietu. Daje to raport o każdym obiekcie w paczce, jego prawdziwym rozmiarze i rozmiarze po spakowaniu, a także informacje o tym, czy został on „usunięty”, a jeśli tak, to pochodzenie łańcucha delta.Aby sprawdzić, czy w repozytorium znajdują się jakieś niezwykle duże obiekty, możesz posortować dane wyjściowe według trzeciej z czwartej kolumny (np
| sort -k3n
.).Z tego wyniku będziesz mógł zobaczyć zawartość dowolnego obiektu za pomocą
git show
polecenia, chociaż nie jest możliwe dokładne zobaczenie, gdzie w historii zatwierdzania repozytorium odwołuje się do obiektu. Jeśli musisz to zrobić, spróbuj czegoś z tego pytania .źródło
Do Twojej wiadomości, największym powodem, dla którego możesz skończyć z niechcianymi obiektami, jest to, że git utrzymuje reflog.
Reflog jest po to, aby uratować twój tyłek, gdy przypadkowo usuniesz gałąź główną lub w inny sposób katastrofalnie uszkodzisz repozytorium.
Najłatwiejszym sposobem rozwiązania tego problemu jest obcięcie plików reflog przed kompresją (po prostu upewnij się, że nigdy nie chcesz wracać do żadnego z zatwierdzeń w reflogu).
Różni się to od
git gc --prune=today
tego, że natychmiast wygasa cały reflog.źródło
Jeśli chcesz dowiedzieć się, które pliki zajmują miejsce w repozytorium git, uruchom
git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5
Następnie wyodrębnij odwołanie do obiektu blob, które zajmuje najwięcej miejsca (ostatnia linia) i sprawdź nazwę pliku, która zajmuje tak dużo miejsca
git rev-list --objects --all | grep <reference>
Może to być nawet plik, który został przez Ciebie usunięty
git rm
, ale git pamięta go, ponieważ nadal istnieją do niego odniesienia, takie jak tagi, piloty i reflog.Gdy już wiesz, jakiego pliku chcesz się pozbyć, polecam skorzystanie z
git forget-blob
https://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-forget-blob/
Jest łatwy w użyciu, po prostu zrób
git forget-blob file-to-forget
Spowoduje to usunięcie każdego odwołania z gita, usunięcie obiektu blob z każdego zatwierdzenia w historii i uruchomienie czyszczenia pamięci, aby zwolnić miejsce.
źródło
Skrypt git-fatfiles z odpowiedzi Vi jest cudowny, jeśli chcesz zobaczyć rozmiar wszystkich twoich plamek, ale jest tak powolny, że nie nadaje się do użytku. Usunąłem limit 40 linii wyjściowych i zamiast kończyć próbę, próbowałem wykorzystać całą pamięć RAM mojego komputera. Więc przepisałem to: jest tysiące razy szybsze, ma dodane funkcje (opcjonalne) i jakiś dziwny błąd został usunięty - stara wersja dawałaby niedokładne liczby, jeśli zsumujesz dane wyjściowe, aby zobaczyć całkowitą przestrzeń używaną przez plik.
Nazwij ten git-fatfiles.pl i uruchom go. Aby zobaczyć miejsce na dysku używane przez wszystkie wersje pliku, użyj
--sum
opcji. Aby zobaczyć to samo, ale dla plików w każdym katalogu, użyj--directories
opcji. Jeśli zainstalujesz moduł Number :: Bytes :: Human cpan (uruchom „cpan Number :: Bytes :: Human”), rozmiary zostaną sformatowane: „21M / ścieżka/do/pliku.mp4”.źródło
Czy na pewno liczysz tylko pliki .pack, a nie pliki .idx? Znajdują się w tym samym katalogu co pliki .pack, ale nie mają żadnych danych repozytorium (jak wskazuje rozszerzenie, są one niczym innym jak indeksami dla odpowiedniego pakietu - w rzeczywistości, jeśli znasz poprawną komendę, możesz łatwo odtworzyć je z pliku pakietu, a sam git robi to podczas klonowania, ponieważ tylko plik pakietu jest przesyłany przy użyciu natywnego protokołu git).
Jako reprezentatywny przykład przyjrzałem się mojemu lokalnemu klonowi repozytorium linux-2.6:
Co wskazuje, że ekspansja o około 7% powinna być powszechna.
Są też pliki na zewnątrz
objects/
; z mojego osobistego doświadczenia, z nichindex
igitk.cache
zwykle są największymi (łącznie 11M w moim klonie repozytorium linux-2.6).źródło
Inne obiekty git przechowywane w
.git
to drzewa, zatwierdzenia i tagi. Zatwierdzenia i znaczniki są małe, ale drzewa mogą być duże, szczególnie jeśli masz bardzo dużą liczbę małych plików w swoim repozytorium. Ile masz plików i ile masz zatwierdzeń?źródło
Czy próbowałeś użyć repackowania git ?
źródło
przed wykonaniem git filter-branch i git gc powinieneś przejrzeć tagi obecne w repozytorium. Każdy prawdziwy system, który ma automatyczne tagowanie dla rzeczy takich jak ciągła integracja i wdrożenia, sprawi, że niechciane obiekty nadal będą odnosić się do tych tagów, dlatego gc nie może ich usunąć i nadal będziesz się zastanawiać, dlaczego rozmiar repozytorium jest nadal tak duży.
Najlepszym sposobem na pozbycie się wszystkich niechcianych rzeczy jest uruchomienie git-filter i git gc, a następnie wypchnięcie mastera do nowego czystego repozytorium. Nowe nagie repozytorium będzie miało oczyszczone drzewo.
źródło
Może się to zdarzyć, jeśli przypadkowo dodałeś dużą porcję plików i umieściłeś je w poczekalni, niekoniecznie zatwierdzając je. Może się to zdarzyć w
rails
aplikacji, gdy uruchomisz,bundle install --deployment
a następnie przypadkowogit add .
zobaczysz wszystkie pliki dodane podvendor/bundle
tobą, aby je usunąć, ale już weszły do historii git, więc musisz zastosować odpowiedź Vi i zmienićvideo/parasite-intro.avi
,vendor/bundle
a następnie uruchomić drugie polecenie, które zapewnia.Widać różnicę, z
git count-objects -v
jaką w moim przypadku skrypt miał przed zastosowaniem rozmiar paczki: 52K a po zastosowaniu 3,8K.źródło
Warto sprawdzić stacktrace.log. Jest to w zasadzie dziennik błędów do śledzenia zatwierdzeń, które się nie powiodły. Niedawno dowiedziałem się, że mój stacktrace.log ma 65,5 GB, a moja aplikacja 66,7 GB.
źródło