Nettoyer l'historique de Git partie 2

Données sensibles ou consommation mémoire trop importante : Il y a de bonnes raisons de vouloir changer l'historique Git. Dans cet article de blog , j'ai expliqué comment purger les fichiers de l'historique Git à l'aide de BFG . Un point faible de BFG est le manque de prise en charge des chemins directs , vous ne pouvez donc pas supprimer spécifiquement des fichiers ou des dossiers dans des sous-dossiers de l'historique. Sur ce, il est temps de chercher des solutions alternatives.


En plus de la branche git filter officiellement déconseillée , git-filter-repo est l'un des outils de nettoyage de l'historique. Après une courte installation , nous analysons d'abord le référentiel et trouvons, par exemple, les plus gros dossiers de l'histoire:

git filter-repo --analyze

Bien être dans le dossier .git/filter-repo/analysis généré toutes sortes de fichiers TXT:

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

Ça vaut le dossier directories-all-sizes.txt regarde plus attentivement:

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

Il arrive souvent que vous ayez longtemps ignoré et supprimé des données HEAD dans l'historique (par exemple, le dossier multimédia WordPress wp-content/uploads/ ou un accidentellement poussé node_modules- ou alors vendor-Liant).

Recommande généralement git-filter-repo après le nettoyage, pousser vers un nouveau référentiel vide. Il y a de nombreuses raisons énumérées ici, pourquoi cela a du sens et évite de nombreux problèmes. Néanmoins, il peut arriver que vous souhaitiez pousser vers le même référentiel et cela est également possible avec quelques astuces.

Surtout, les principales plateformes d'hébergement de code GitHub et GitLab recommandent différentes approches, dont certaines diffèrent les unes des autres. Par exemple, sur GitHub, nous supprimons wp-content/uploads/ en suivant les étapes suivantes git-filter-repo de l'histoire:

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

Nous pouvons désormais également vérifier la taille à distance (la modification de la taille via l'API et dans l'interface utilisateur peut prendre jusqu'à 24 heures). Pour ce faire, ouvrez les paramètres du référentiel (si le référentiel appartient à une organisation, vous devez d'abord ajouter votre propre compte à l'organisation). Maintenant, nous voyons la taille:

GitHub : espace disque avant le nettoyage
GitHub : espace disque après le nettoyage

La procédure est légèrement différente sur 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

Après une autre attente d'environ 5 minutes, nous pouvons passer sous Settings > Usage Quotas voir l'espace de stockage:

GitLab : espace disque avant le nettoyage
GitLab : espace disque après nettoyage

Après la suppression, il est important que tous les développeurs impliqués soient impliqués dans les étapes finales : si un utilisateur effectue maintenant une poussée normale avec sa propre copie locale, cela entraînerait la migration des fichiers volumineux vers le référentiel central. Par conséquent, les 3 options suivantes sont recommandées:

  • "le clone frais du pauvre"
    • rm -rf .git && git clone xxx temp && mv temp/.git ./.git && rm -rf temp
    • Pour les fichiers modifiés (selon l'application): git checkout -- . ou. git add -A . && git commit -m "Push obscure file changes." && git push
  • "commencer à partir de zéro"
    • rm -rf repo && git clone xxx .
  • "pull laid avec rebase"
    • git pull -r
    • Ici, vous avez toujours l'historique non nettoyé, mais dans la plupart des cas, vous n'écrasez plus accidentellement le référentiel distant avec la grande variante locale

Dans le cadre des quotas actuels (notamment en raison des nouvelles restrictions de GitLab ), il est toujours intéressant de vérifier la taille de l'historique de vos dépôts et de les nettoyer si nécessaire:

GitHub GratuitGratuit
Limite de taille de fichier maximale100 Mo
Limite de taille maximale du dépôt5 000 Mo
Limite maximale du nombre de dépôts
Limite de taille globale maximale5 000 Mo

Enfin, il vaut également la peine de jeter un œil à une variante gratuite auto-hébergée comme Gitéa lancer. Avec peu d'effort, vous pouvez sur un serveur très fin une instance Git auto-hébergée (GUI par SSL sécurisé, Sauvegarde inclus, contrôle sur API puissante) hôte, qui sont également excellents configurer et est également supérieur en termes de protection des données. Ici, au fait, vous pouvez également utiliser git-filter-repo Rationalisez simplement les référentiels:

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

Voici précisément la commande sudo -u git git gc --aggressive --prune=now important (le cron en cours d'exécution git gc sinon en a un trop long temps de taille de 2 semaines).

Retour