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:
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:
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 gratis | GitLab gratis | |
Maximale bestandsgroottelimiet | 100 MB | ∞ |
Maximale repo-groottelimiet | 5.000 MB | ∞ |
Maximum aantal repo's | ∞ | ∞ |
Maximale totale groottelimiet | ∞ | 5.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).