Dati sensibili o consumo eccessivo di memoria: ci sono buone ragioni per voler cambiare la cronologia di Git. In questo post del blog , ho spiegato come eliminare i file dalla cronologia di Git utilizzando BFG . Un punto debole di BFG è la mancanza di supporto per i percorsi diretti , quindi non è possibile rimuovere in modo specifico file o cartelle nelle sottocartelle dalla cronologia. Detto ciò, è tempo di cercare soluzioni alternative.
Oltre al ramo git filter ufficialmente sconsigliato , git-filter-repo è uno degli strumenti per ripulire la cronologia. Dopo una breve installazione , analizziamo prima il repository e troviamo, ad esempio, le cartelle più grandi della storia:
git filter-repo --analyze
Ben essere nella cartella .git/filter-repo/analysis
generato tutti i tipi di file TXT:
directories-all-sizes.txt
extensions-all-sizes.txt
path-all-sizes.txt
- ...
Vale il file directories-all-sizes.txt
dai un'occhiata più da vicino:
=== 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
...
Succede spesso di aver ignorato e rimosso a lungo i dati HEAD nella cronologia (ad esempio, la cartella multimediale di WordPress wp-content/uploads/
o uno spinto accidentalmente node_modules
- o vendor
-Raccoglitore).
Generalmente consiglia git-filter-repo
dopo la pulizia, il push in un nuovo repository vuoto. Ci sono numerose ragioni elencate qui, perché questo ha senso ed evita molti problemi. Tuttavia, può succedere di voler eseguire il push sullo stesso repository e ciò è possibile anche con alcuni suggerimenti.
È importante sottolineare che le principali piattaforme di hosting di codice GitHub e GitLab consigliare approcci diversi, alcuni dei quali differiscono tra loro. Ad esempio, su GitHub rimuoviamo wp-content/uploads/
utilizzando i seguenti passaggi git-filter-repo
dalla storia:
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
Ora possiamo anche controllare le dimensioni da remoto (la modifica delle dimensioni tramite API e nell'interfaccia utente può richiedere fino a 24 ore). Per fare ciò, apri le impostazioni del repository (se il repository appartiene a un'organizzazione, devi prima aggiungere il tuo account all'organizzazione). Ora vediamo la dimensione:
La procedura è leggermente diversa su 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
Dopo un'altra attesa di circa 5 minuti possiamo andare sotto Settings > Usage Quotas
visualizzare lo spazio di archiviazione:
Dopo la rimozione, è importante che tutti gli sviluppatori coinvolti siano coinvolti nei passaggi finali: se un utente ora esegue un normale push con la propria copia locale, ciò comporterebbe la migrazione di file di grandi dimensioni al repository centrale. Pertanto, sono consigliate le seguenti 3 opzioni:
- "il clone fresco del povero"
rm -rf .git && git clone xxx temp && mv temp/.git ./.git && rm -rf temp
- Per file modificati (a seconda dell'applicazione):
git checkout -- .
o.git add -A . && git commit -m "Push obscure file changes." && git push
- "iniziare da zero"
rm -rf repo && git clone xxx .
- "brutto tiro con rebase"
git pull -r
- Qui hai ancora la cronologia non pulita, ma nella maggior parte dei casi non sovrascrivi più accidentalmente il repository remoto con la variante large local
Nel corso delle attuali quote (soprattutto a causa delle nuove restrizioni di GitLab ), vale sempre la pena controllare la dimensione della cronologia dei tuoi repository e ripulirli se necessario:
GitHub gratuito | GitLab gratuito | |
Limite massimo della dimensione del file | 100 MB | ∞ |
Limite massimo della dimensione del repository | 5.000 MB | ∞ |
Limite massimo di conteggio dei repo | ∞ | ∞ |
Limite massimo di dimensioni complessive | ∞ | 5.000 MB |
Infine, vale anche la pena dare un'occhiata a una variante gratuita self-hosted come Gitea gettare. Con poco sforzo puoi su a server molto sottile un'istanza Git self-hosted (GUI per SSL protetto, Backup incluso, controllo potente API) host, anch'essi eccellenti configurare ed è anche superiore in termini di protezione dei dati. Qui, tra l'altro, puoi anche usare git-filter-repo
Semplifica semplicemente i repository:
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
Ecco in particolare il comando sudo -u git git gc --aggressive --prune=now
importante (il cron in esecuzione git gc
altrimenti ne ha uno troppo lungo tempo di potatura di 2 settimane).