Rensa upp Git-historik del 2

Känslig data eller för mycket minnesförbrukning: Det finns goda skäl att vilja ändra Git-historiken. I det här blogginlägget förklarade jag hur man rensar filer från Git-historiken med BFG . En svag punkt med BFG är bristen på stöd för direkta sökvägar , så du kan inte specifikt ta bort filer eller mappar i undermappar från historiken. Med det är det dags att titta på alternativa lösningar.


Förutom den officiellt inte rekommenderade git filtergrenen är git-filter-repo ett av verktygen för att rensa upp historien. Efter en kort installation analyserar vi först förvaret och hittar till exempel de största mapparna i historien:

git filter-repo --analyze

Var väl i mappen .git/filter-repo/analysis genererade alla möjliga TXT-filer:

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

Det är värt filen directories-all-sizes.txt ta en närmare titt:

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

Det händer ofta att du länge har ignorerat och tagit bort från HEAD-data i historiken (till exempel WordPress-mediamappen wp-content/uploads/ eller en av misstag knuffad node_modules- eller vendor-Pärm).

Rekommenderar i allmänhet git-filter-repo efter rengöring, tryck till ett nytt, tomt förråd. Det finns många skäl som anges här, varför detta är vettigt och undviker många problem. Ändå kan det hända att du vill pusha till samma förråd och det är också möjligt med några tips.

Viktigt, de stora kodvärdplattformarna GitHub och GitLab rekommendera olika tillvägagångssätt, varav några skiljer sig från varandra. Till exempel på GitHub tar vi bort wp-content/uploads/ med hjälp av följande steg git-filter-repo från historien:

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

Vi kan nu även kontrollera storleken på distans (att ändra storleken via API och i UI kan ta upp till 24 timmar). För att göra detta, öppna förvarets inställningar (om förvaret tillhör en organisation måste du först lägga till ditt eget konto i organisationen). Nu ser vi storleken:

GitHub: diskutrymme före rensning
GitHub: diskutrymme efter rensning

Proceduren är något annorlunda på 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

Efter ytterligare en väntan på ~5 minuter kan vi gå under Settings > Usage Quotas se lagringsutrymme:

GitLab: diskutrymme före rensning
GitLab: diskutrymme efter rensning

Efter borttagningen är det viktigt att alla inblandade utvecklare är involverade i de sista stegen: Om en användare nu utför en normal push med sin egen lokala kopia skulle detta resultera i att de stora filerna migrerar tillbaka till det centrala förvaret. Därför rekommenderas följande 3 alternativ:

  • "fattigmans färska klon"
    • rm -rf .git && git clone xxx temp && mv temp/.git ./.git && rm -rf temp
    • För ändrade filer (beroende på applikation): git checkout -- . eller. git add -A . && git commit -m "Push obscure file changes." && git push
  • "börja från början"
    • rm -rf repo && git clone xxx .
  • "fult drag med rebas"
    • git pull -r
    • Här har du fortfarande den orenade historiken, men i de flesta fall skriver du inte längre av misstag över fjärrförvaret med den stora lokala varianten

Under de nuvarande kvoterna (särskilt på grund av de nya begränsningarna av GitLab ), är det alltid värt att kontrollera storleken på historiken för dina förvar och rensa upp dem om det behövs:

GitHub gratisGitLab gratis
Max filstorleksgräns100 MB
Max repostorleksgräns5 000 MB
Max antal repor
Max total storleksgräns5 000 MB

Slutligen är det också värt att ta en titt på en självvärd, gratis variant som Gitea att kasta. Med liten ansträngning kan du på en mycket smal server en självvärderad Git-instans (GUI per SSL säkrad, Säkerhetskopiering ingår, kontroll över kraftfullt API) värd, som också är utmärkta konfigurera och är också överlägsen när det gäller dataskydd. Här kan du förresten också använda git-filter-repo Effektivisera helt enkelt förråd:

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

Här är kommandot specifikt sudo -u git git gc --aggressive --prune=now viktigt (cron kör git gc annars har en för lång beskära tid 2 veckor).

Tillbaka