Git : supprimer un fichier de l'historique
Par le passé, vous avez ajouté dans votre dépôt Git de gros fichiers que vous avez supprimés ensuite. Hors, la taille de votre dépôt Git reste conséquent à cause de ces gros fichiers qui sont apparus au moins une fois dans votre historique Git. Bonne nouvelle, nous pouvons les supprimer purement et simplement pour les retirer de l'historique et diminuer la taille de votre dépôt Git !Vous avez ajouté des fichiers contenant des mots de passes ou des données sensibles que vous souhaitez faire disparaitre de votre dépôt Git ? Bonne nouvelle, nous pouvons supprimer ces fichiers purement et simplement !
Sauvegardez votre dépôt avant toute manipulation
Une mauvaise manipulation peut toujours arriver. Je vous conseille de sauvegarder votre dépôt avant toutes manipulations :tar -zcvf monDepotGit.tar.gz monProjet/Lister les fichiers les plus volumineux de votre dépôt Git
Vous pouvez exécuter cette commande pour obtenir la liste des fichiers les plus volumineux de votre historique Git. Utile pour repérer quels fichiers prennent le plus de place dans votre historique et pour diminuer la taille de votre dépôt Git facilement et rapidement :git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | sed -n 's/^blob //p' | sort --numeric-sort --key=2 | cut -c 1-12,41- | $(command -v gnumfmt || echo numfmt) --field=2 --to=iec-i --suffix=B --padding=7 --round=nearestc/Mes documents/MonProjet
$ git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | sed -n 's/^blob //p' | sort --numeric-sort --key=2 | cut -c 1-12,41- | $(command -v gnumfmt || echo numfmt) --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest
e69de29bb2d1      0B var/cache/.gitkeep
2ec067f4c707     65B app/config/routing.yml
fd781ca99a0e     73B README.md
639ec2cd7e82    101B app/AppCache.php
05123b6782ff    113B src/AppBundle/AppBundle.php
4665fcae34a9    116B web/robots.txt
ada7e896548b    135B .htaccess
fb1de45bdb33    143B app/.htaccess
9e4815e604ee    209B src/AppBundle/Resources/views/templates/form/form_label.html.twig
02af762af528    210B src/AppBundle/Resources/views/templates/form/form_label.html.twig
394acfa93e93    233B src/AppBundle/Repository/PhotoRepository.php
6c198ea3cc55    234B src/AppBundle/Repository/PhotoRepository.php
470d7e198277    235B src/AppBundle/Repository/MembreRepository.php
47d46a2a15a4    236B src/AppBundle/Repository/MembreRepository.php
9ae1874a1911    239B src/AppBundle/Repository/CommandeRepository.php
be400ab8fa86    239B src/AppBundle/Repository/VetementRepository.php
e4ceeb628695    239B src/AppBundle/Repository/BlogPostRepository.php
10408065ee96    240B src/AppBundle/Repository/BlogPostRepository.php
5badf55d9d3f    240B src/AppBundle/Repository/CommandeRepository.php
ccbc627d9a03    240B src/AppBundle/Repository/VetementRepository.php
324260516d62    260B web/old1/plugins/rs/assets/white50.png
2f75ca1ce9d9    265B .gitignore
d20e6b7cadba    269B src/AppBundle/Resources/views/emails/user_registration.txt.twig
2f6d92503ffe    270B app/config/config_test.yml
[...]
f7d1a8bca226  2,6MiB web/photos/photo_2.jpg
7c31f7f00830  2,9MiB web/photos/photo_3.jpg
522f184cf9aa  3,7MiB web/photos/photo_1.jpg
0231ea1ac1f5  3,8MiB web/photos/photo_5.jpg
585901004a81  4,4MiB web/photos/photo_4.jpg
web/photos/* sont des photos que j'ai un jour utilisé dans mon projet, que je n'utilise plus, que j'ai supprimées, mais qui sont encore présentes dans l'historique Git.Je n'aurais jamais du ajouter ces photos à mon historique, ne débattons pas sur le pourquoi, voyons comment les supprimer purement et simplement pour faire comme si elles n'avaient jamais existées dans l'historique Git.
Outils facilitant la tâches
Sur internet, vous pourrez trouver des outils plus ou moins bien permettant de supprimer des fichiers de notre historique Git. Chacun ont des méthodes différentes pour le faire.Il y a BFG Repo Cleaner qui permet de faire pas mal de chose assez facilement. Il nécessite d'avoir Java d'installé sur son ordinateur.
Par contre, il ne permet pas de supprimer un fichier précis facilement.
Pour supprimer un fichier précis de l'historique, vous devez retrouver l'identifiant unique de ce fichier
Vous pouvez retrouver l'identifiant d'un fichier grâce à cette commande :
git log --all --pretty=format:%H -- web/photos/photo_4.jpg | xargs -n1 -I% sh -c "git ls-tree % -- web/photos/photo_4.jpg"web/photos/photo_4.jpg par le fichier que vous recherchez dans votre dépôt.Si trop de commits apparaissent, vous pouvez filtrer les résultats d'un commit en particulier en utilisant :
git log --all --pretty=format:%H -- web/photos/photo_4.jpg | xargs -n1 -I% sh -c "git ls-tree % -- web/photos/photo_4.jpg | grep -q 9d84ffg6 && echo %"9d84ffg6 est le début de l'identifiant de votre commit.Enfin, si vous souhaitez afficher tous les objets présents dans votre historique Git, vous pouvez faire ceci (attention, la liste risque d'être longue) :
git rev-list --all --objectsUtiliser git filter-branch
La méthode la plus sûre, mais peut-être la plus longue a s'exécuter, surtout si votre historique Git est conséquent, reste d'utiliser les commandes Git dédiées à cet usage.(Pour voir la différence de taille avant et après la manipulation, vous pouvez noter la taille de votre dossier
.git avant d'exécuter les prochaines commandes)Pour supprimer un fichier précis de votre historique, de tous les commits, de toutes les branches, vous pouvez utilisez :
git filter-branch --tree-filter 'rm -f web/photos/photo_4.jpg' HEAD --allgit filter-branch --tree-filter 'rm -f web/photos/photo_4.jpg' HEADVous pouvez supprimer plusieurs fichiers à la fois en séparant les chemins par un espace, comme ceci :
git filter-branch --tree-filter 'rm -f web/photos/photo_4.jpg web/photos/photo_5.jpg web/photos/...' HEAD --allgit filter-branch -f --tree-filter 'rm -f "web/photos de vacances/moi.jpg" "web/photos de vacances/nous.jpg" ' HEAD --allGit prend beaucoup de précautions dans ses actes. Une fois cette commande exécutée, si vous regardez votre historique, vous vous retrouvez avec des branches ressemblant à
refs/original/refs/heads/master. Elles correspondent à un backup de vos branches avant la manipulation.Vu que ce backup est toujours présent, vous comprendrez que la taille de votre historique Git n'a pas encore diminué.
Il y a plusieurs méthodes pour supprimer ces branches de backup. Je vous propose de refaire un
git filter-branch qui n'effectue aucune action pour supprimer cet ancien backup et en créé un nouveau qui est, en réalité, un copier/coller de votre branche actuelle sans modification :git filter-branch -f --tree-filter ' ' HEAD --allVous pouvez réitérer l'opération autant de fois que vous le souhaitez, comme ceci :
git filter-branch -f --tree-filter 'rm -f "web/photos de vacances/moi.jpg" "web/photos de vacances/nous.jpg" ' HEAD --all
git filter-branch -f --tree-filter 'rm -f "web/photos de vacances/les autres.jpg" "web/photos de vacances/les voisins.jpg" ' HEAD --all
git filter-branch -f --tree-filter 'rm -f "web/photos de vacances/la plage.jpg" "web/photos de vacances/la montagne.jpg" ' HEAD --all
git filter-branch -f --tree-filter ' ' HEAD --all # Pour supprimer les anciens backupUne fois que vous avez supprimé les fichiers inutiles que vous ne souhaitez pas garder dans votre historique, vous devez dire à Git de se débarrasser des objets qui ne sont plus liés à aucun commit de votre historique Git, comme ceci :
git reflog expire --expire-unreachable=all --all
git gc --aggressive --prune=now(Vous pouvez maintenant retourner voir la taille de votre dossier
.git, celle-ci doit avoir diminué en fonction de la taille des éléments que vous avez supprimés)La dernière chose à faire est de pousser toutes vos modifications sur votre dépôt distant :
git push -f --all-f sert à forcer le git push malgré la réécriture de l'historique Git et --all sert à pousser toutes vos branches.Vous pouvez avoir plus d'informations sur la commande
git filter-branch sur sa documentation officielle.Sources
- Recherche "bfg repo cleaner"
- Recherche "get git object id"
- Recherche "git filter branch"
- Recherche "git log one commit"
- Recherche "git delete backup"
- Recherche "git push all"
- Recherche "linux gzip folder"
- Recherche "git delete backup"
Une erreur ? une question ? une critique ? une faute ? un conseil ? ou tout simplement un merci ?
Lâche ton commentaire
				ko4la Le lundi 13 janvier 2025 à 09:06:06
				
Très bon article. Merci pour la description des mécanismes. J'ai dans mon cas de figure une chaine orpheline qui s'est créée. Le git concerné possède des PR et des versions et celles-ci se retrouvent sur une chaine orpheline. Ca pourrait être un sujet additionnel dans cet article.
				Très bon article. Merci pour la description des mécanismes. J'ai dans mon cas de figure une chaine orpheline qui s'est créée. Le git concerné possède des PR et des versions et celles-ci se retrouvent sur une chaine orpheline. Ca pourrait être un sujet additionnel dans cet article.