Oczyść historię Gita, część 2

Poufne dane lub zbyt duże zużycie pamięci: istnieją dobre powody, aby chcieć zmienić historię Git. W tym poście na blogu wyjaśniłem, jak usunąć pliki z historii Git przy użyciu BFG . Słabym punktem BFG jest brak obsługi ścieżek bezpośrednich , przez co nie można specjalnie usuwać z historii plików lub folderów w podfolderach. Po tym nadszedł czas, aby przyjrzeć się alternatywnym rozwiązaniom.


Oprócz oficjalnie niezalecanej gałęzi git filter git-filter-repo jest jednym z narzędzi do czyszczenia historii. Po krótkiej instalacji najpierw analizujemy repozytorium i znajdujemy np. największe foldery w historii:

git filter-repo --analyze

Bądź w folderze .git/filter-repo/analysis wygenerował wszystkie rodzaje plików TXT:

  • directories-all-sizes.txt
  • extensions-all-sizes.txt
  • path-all-sizes.txt
  • ...

Warto plik directories-all-sizes.txt przyjrzyj się bliżej:

=== All directories by reverse size ===

Format: unpacked size, packed size, date deleted, directory name

  4624417043 3796607988 <present> <toplevel>
  4475940396 3778033787 <present> wp-content
  4060236681 3694449320 <present> wp-content/uploads
   305163809   70576241 <present> wp-content/plugins
   123818107   15442735 <present> wp-includes
...

Często zdarza się, że od dawna zignorowałeś i usunąłeś z HEAD dane w historii (na przykład folder multimediów WordPressa) wp-content/uploads/ lub przypadkowo popchnięty node_modules- lub vendor-Spoiwo).

Co ważne, główne platformy hostingowe kodu GitHub oraz GitLab polecam różne podejścia, z których niektóre różnią się od siebie. Na przykład na GitHub usuwamy wp-content/uploads/ wykonując następujące czynności git-filter-repo z historii:

mkdir tmp-repo
cd tmp-repo
git clone git@github.com:foo/bar.git .
cp .git/config /tmp/config-backup
git filter-repo --invert-paths --path wp-content/uploads
mv /tmp/config-backup .git/config
git push origin --force --all
git push origin --force --tags
# check size locally
git gc && git count-objects -vH
cd ..
rm -rf tmp-repo

Teraz możemy również sprawdzić rozmiar zdalnie (zmiana rozmiaru przez API i w interfejsie użytkownika może zająć do 24 godzin). Aby to zrobić, otwórz ustawienia repozytorium (jeśli repozytorium należy do organizacji, musisz najpierw dodać własne konto do organizacji). Teraz widzimy rozmiar:

GitHub: miejsce na dysku przed czyszczeniem
GitHub: miejsce na dysku po czyszczeniu

Procedura jest nieco inna na GitLab:

mkdir tmp-repo
cd tmp-repo
# Settings > General > Advanced > Export project > download tar.gz file into tmp-repo
tar xzf 20*.tar.gz
git clone --bare --mirror project.bundle
cd project.git
git filter-repo --invert-paths --path wp-content/uploads/
cp ./filter-repo/commit-map /tmp/commit-map-1
# copying the commit-map has to be done after every single command from git filter-repo
# you need the commit-map files later
git remote remove origin
git remote add origin git@gitlab.com:foo/bar.git
# Settings > Repository > Protected branches/Protected branches >
# enable "Allowed to force push to main/master"
git push origin --force 'refs/heads/*'
git push origin --force 'refs/tags/*'
git push origin --force 'refs/replace/*'
# Settings > Repository > Protected branches/Protected branches >
# disable "Allowed to force push on main/master"
cd ./../../
rm -rf tmp-repo
date
# wait 30 minutes (😱)
date
# Settings > Repository > upload /tmp/commit-map-X

Po kolejnym oczekiwaniu ~5 minut możemy zejść pod Settings > Usage Quotas zobacz miejsce do przechowywania:

GitLab: miejsce na dysku przed czyszczeniem
GitLab: miejsce na dysku po czyszczeniu

Po usunięciu ważne jest, aby wszyscy zaangażowani programiści byli zaangażowani w ostatnie kroki: jeśli użytkownik wykona teraz normalne push z własną lokalną kopią, spowoduje to migrację dużych plików z powrotem do centralnego repozytorium. Dlatego zalecane są następujące 3 opcje:

  • rm -rf .git && git clone xxx temp && mv temp/.git ./.git && rm -rf temp && git add -A .
    („świeży klon biednego człowieka”, sklonuj ponownie do istniejącego repozytorium)
  • rm -rf repo && git clone xxx .
    („zacznij od zera”, najczystszy wariant)
  • git pull -r
    („wyciągnij z rebasem”, nadal masz nieoczyszczoną historię, ale nie nadpisujesz już przypadkowo)

W trakcie obecnych kwot (szczególnie ze względu na nowe ograniczenia GitLab ) zawsze warto sprawdzić rozmiar historii swoich repozytoriów i w razie potrzeby je wyczyścić:

GitHub za darmoBezpłatne GitLab
Maksymalny rozmiar pliku100MB
Maksymalny limit rozmiaru repo5000 MB
Maksymalny limit liczby repo
Maksymalny całkowity limit rozmiaru5000 MB

Na koniec warto również przyjrzeć się samo-hostowanej, darmowej odmianie, takiej jak Gitea . Przy niewielkim wysiłku możesz hostować samoobsługową instancję Git (GUI zabezpieczony przez SSL , w tym kopia zapasowa , kontrola za pośrednictwem wydajnego API ) na bardzo oszczędnym serwerze , który można również doskonale skonfigurować i jest również lepszy pod względem ochrony danych.

Plecy