Jak wspomniano w tej odpowiedzi SO , git gc
może faktycznie zwiększyć rozmiar repozytorium!
Zobacz także ten wątek
Teraz git ma mechanizm bezpieczeństwa, aby nie usuwać obiektów bez odniesień od razu po uruchomieniu ' git gc
'.
Domyślnie obiekty, do których nie ma odniesień, są przechowywane przez okres 2 tygodni. Ma to na celu ułatwienie odzyskania przypadkowo usuniętych gałęzi lub zatwierdzeń, lub uniknięcie wyścigu, w którym właśnie utworzony obiekt będący w trakcie, ale jeszcze nie przywoływany, mógłby zostać usunięty przez git gc
równoległy proces „ ”.
Tak więc, aby dać ten okres karencji spakowanym, ale bez odniesień obiektom, proces przepakowywania wypycha je z opakowania do ich luźnej formy, aby można je było postarzać i ostatecznie przyciąć.
Obiekty, do których nie ma odniesień, zwykle nie są jednak tak liczne. Posiadanie 404855 obiektów bez odwołań to całkiem sporo, a wysyłanie tych obiektów w pierwszej kolejności przez klon jest głupie i kompletnym marnotrawstwem przepustowości sieci.
W każdym razie ... Aby rozwiązać problem, wystarczy uruchomić ' git gc
' z --prune=now
argumentem, aby wyłączyć ten okres karencji i od razu pozbyć się tych obiektów, do których nie ma odniesienia (bezpieczne tylko wtedy, gdy żadne inne działania git nie są wykonywane w tym samym czasie, co powinno być łatwe do zapewnienia na stacji roboczej).
A tak przy okazji, użycie „ git gc --aggressive
” z późniejszą wersją git (lub „ git repack -a -f -d --window=250 --depth=250
”)
Ten sam wątek wspomina :
git config pack.deltaCacheSize 1
Ogranicza to rozmiar pamięci podręcznej delta do jednego bajtu (skutecznie go wyłączając) zamiast domyślnej wartości 0, co oznacza nieograniczoną. Dzięki temu jestem w stanie przepakować to repozytorium za pomocą powyższego git repack
polecenia na systemie x86-64 z 4 GB pamięci RAM i przy użyciu 4 wątków (jest to czterordzeniowy rdzeń). Zużycie pamięci rezydentnej rośnie jednak do prawie 3,3 GB.
Jeśli twoja maszyna jest SMP i nie masz wystarczającej ilości pamięci RAM, możesz zmniejszyć liczbę wątków tylko do jednego:
git config pack.threads 1
Dodatkowo możesz dodatkowo ograniczyć użycie pamięci za pomocą --window-memory argument
to ' git repack
'.
Na przykład użycie --window-memory=128M
powinno utrzymywać rozsądną górną granicę wykorzystania pamięci wyszukiwania różnicowego, chociaż może to skutkować mniej optymalnym dopasowaniem delta, jeśli repozytorium zawiera wiele dużych plików.
Na froncie filtru można rozważyć (ostrożnie) ten skrypt
#!/bin/bash
set -o errexit
# Author: David Underhill
# Script to permanently delete files/folders from your git repository. To use
# it, cd to your repository's root and then run the script with a list of paths
# you want to delete, e.g., git-delete-history path1 path2
if [ $# -eq 0 ]; then
exit 0
fi
# make sure we're at the root of git repo
if [ ! -d .git ]; then
echo "Error: must run this script from the root of a git repository"
exit 1
fi
# remove all paths passed as arguments from the history of the repo
files=$@
git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $files" HEAD
# remove the temporary history git-filter-branch otherwise leaves behind for a long time
rm -rf .git/refs/original/ && git reflog expire --all && git gc --aggressive --prune