Ruim Git-geschiedenis op deel 2

Gevoelige gegevens of te veel geheugengebruik: er zijn goede redenen om de Git-geschiedenis te willen wijzigen. In deze blogpost heb ik uitgelegd hoe je met BFG bestanden uit de Git-geschiedenis kunt opschonen. Een zwak punt van BFG is het gebrek aan ondersteuning voor directe paden , waardoor je niet specifiek bestanden of mappen in submappen uit de geschiedenis kunt verwijderen. Daarmee is het tijd om naar alternatieve oplossingen te kijken.


Naast de officieel niet aanbevolen git filter branch , is git-filter-repo een van de tools voor het opschonen van de geschiedenis. Na een korte installatie analyseren we eerst de repository en vinden we bijvoorbeeld de grootste mappen in de geschiedenis:

git filter-repo --analyze

Wel in de map .git/filter-repo/analysis alle soorten TXT-bestanden gegenereerd:

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

Het is het bestand waard directories-all-sizes.txt kijk eens van dichterbij:

=== 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
...

Het komt vaak voor dat je de HEAD-gegevens in de geschiedenis lang hebt genegeerd en verwijderd (bijvoorbeeld de WordPress-mediamap wp-content/uploads/ of een per ongeluk ingedrukte node_modules- of vendor-Binder).

Over het algemeen aanbevolen git-filter-repo na het opschonen, doorschuiven naar een nieuwe, lege repository. Er zijn hier tal van redenen vermeld, waarom dit logisch is en veel problemen voorkomt. Toch kan het voorkomen dat je naar dezelfde repository wil pushen en dat kan ook met een paar hints.

Belangrijk is dat de belangrijkste code-hostingplatforms GitHub en GitLab verschillende benaderingen aanbevelen, waarvan sommige van elkaar verschillen. Op GitHub verwijderen we bijvoorbeeld wp-content/uploads/ met behulp van de volgende stappen: git-filter-repo uit de geschiedenis:

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/
# option 1: same repo
  mv /tmp/config-backup .git/config
  git push origin --force --all
# option 2: new repo
  git remote add origin git@github.com:foo/bar-new.git
  git push origin --force --all
cd ..
rm -rf tmp-repo

We kunnen nu ook de maat op afstand controleren (het wijzigen van de maat via API en in de UI kan tot 24 uur duren). Open hiervoor de repository-instellingen (als de repository bij een organisatie hoort, moet je eerst je eigen account aan de organisatie toevoegen). Nu zien we de maat:

GitHub: schijfruimte voor opschonen
GitHub: schijfruimte na opschonen

De procedure is iets anders op GitLab:

mkdir tmp-repo
cd tmp-repo
# option 1: same 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 to main/master"
  date
  # wait 30 minutes (😱)
  date
  # Settings > Repository > upload /tmp/commit-map-X
# option 2: new repo
  git clone git@gitlab.com:foo/bar.git .
  git filter-repo --invert-paths --path wp-content/uploads/
  git remote add origin git@gitlab.com:foo/bar-new.git
  # Settings > Repository > Protected branches/Protected branches >
  # enable "Allowed to force push to main/master"
  git push origin --force --all
  # Settings > Repository > Protected branches/Protected branches >
  # disable "Allowed to force push to main/master"
cd ..
rm -rf tmp-repo

Na nog een wachttijd van ~5 minuten kunnen we onder gaan Settings > Usage Quotas opslagruimte bekijken:

GitLab: schijfruimte voor opschonen
GitLab: schijfruimte na opschonen

Na de verwijdering is het belangrijk dat alle betrokken ontwikkelaars worden betrokken bij de laatste stappen: Als een gebruiker nu een normale push uitvoert met zijn eigen lokale kopie, zou dit ertoe leiden dat de grote bestanden terug migreren naar de centrale repository. Daarom worden de volgende 3 opties aanbevolen::

  • "de verse kloon van de arme man"
    • rm -rf .git && git clone xxx temp && mv temp/.git ./.git && rm -rf temp
    • Voor gewijzigde bestanden (afhankelijk van de toepassing): git checkout -- . of. git add -A . && git commit -m "Push obscure file changes." && git push
  • "vanaf nul beginnen"
    • rm -rf repo && git clone xxx .
  • "lelijke trek met rebase"
    • git pull -r
    • Hier heb je nog de ongereinigde geschiedenis, maar in de meeste gevallen overschrijf je niet meer per ongeluk de remote repository met de grote lokale variant

In de loop van de huidige quota's (vooral vanwege de nieuwe beperkingen van GitLab ), is het altijd de moeite waard om de grootte van de geschiedenis van uw repositories te controleren en indien nodig op te schonen:

GitHub gratisGitLab gratis
Maximale bestandsgroottelimiet100 MB
Maximale repo-groottelimiet5.000 MB
Maximum aantal repo's
Maximale totale groottelimiet5.000 MB

Ten slotte is het ook de moeite waard om eens te kijken naar een zelf-gehoste, gratis variant zoals Gitea gooien. Met weinig moeite kun je op een zeer slanke server een zelf-gehoste Git-instantie (GUI per SSL beveiligd, Back-up inbegrepen, controle over krachtige API) gastheer, die ook uitstekend zijn? configureren en is ook superieur op het gebied van gegevensbescherming. Hier kun je trouwens ook gebruik maken van git-filter-repo Stroomlijn eenvoudig opslagplaatsen:

mkdir tmp-repo
cd tmp-repo
git clone git@git.tld.com:foo/bar.git .
cp .git/config /tmp/config-backup
git filter-repo --invert-paths --path wp-content/uploads/
# option 1: same repo
  mv /tmp/config-backup .git/config
  git push origin --mirror
  # login on the remote command line and run in the repo-folder
  sudo -u git git reflog expire --expire=now --all
  sudo -u git git gc --aggressive --prune=now
  # if you face memory limit issues, modify the git configuration
  sudo -u git git config --global pack.windowMemory "100m"
  sudo -u git git config --global pack.packSizeLimit "100m"
  sudo -u git git config --global pack.threads "1"
  # if in web ui the size does not change, make a slight
  # modification to a file and push again normally
# option 2: new repo
  git remote add origin git@git.tld.com:foo/bar-new.git
  git push origin --force --all
cd ..
rm -rf tmp-repo

Hier is specifiek het commando sudo -u git git gc --aggressive --prune=now belangrijk (de cron draait) git gc anders heeft een te lang snoei tijd van 2 weken).

Terug