115 votes

Comment supprimer les objets inutilisés d'un dépôt git ?

J'ai accidentellement ajouté, commis et poussé un énorme fichier binaire avec mon tout dernier commit dans un dépôt Git.

Comment puis-je faire en sorte que Git supprime le(s) objet(s) qui a/ont été créé(s) pour ce commit afin que ma .git le répertoire se rétrécit à nouveau à une taille raisonnable ?

Modifier : Merci pour vos réponses ; j'ai essayé plusieurs solutions. Aucune n'a fonctionné. Par exemple, celle de GitHub a supprimé les fichiers de l'historique, mais l'option .git La taille du répertoire n'a pas diminué :

$ BADFILES=$(find test_data -type f -exec echo -n "'{}' " \;)

$ git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $BADFILES" HEAD
Rewrite 14ed3f41474f0a2f624a440e5a106c2768edb67b (66/66)
rm 'test_data/images/001.jpg'
[...snip...]
rm 'test_data/images/281.jpg'
Ref 'refs/heads/master' was rewritten

$ git log -p # looks nice

$ rm -rf .git/refs/original/
$ git reflog expire --all
$ git gc --aggressive --prune
Counting objects: 625, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (598/598), done.
Writing objects: 100% (625/625), done.
Total 625 (delta 351), reused 0 (delta 0)

$ du -hs .git
174M    .git
$ # still 175 MB :-(

15 votes

Juste un rappel pour les modérateurs, cette question appartient à 100% à SO, pas à superuser.

0 votes

Comme mentionné ici ( stackoverflow.com/questions/685319/ ), avez-vous essayé un repack après votre gc ? git-repack -a suivi par git-prune-packed par exemple. Voir blog.felipebalbi.com/2007/12/19/

159voto

Sam Watkins Points 1299

J'ai répondu à cette question ailleurs, et je vais la copier ici puisque j'en suis fier !

... et sans plus attendre, puis-je vous présenter cet utile script, git-gc-all, garanti pour supprimer toutes vos ordures git jusqu'à ce qu'elles puissent venir avec des variables de configuration supplémentaires :

git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 \
  -c gc.rerereresolved=0 -c gc.rerereunresolved=0 \
  -c gc.pruneExpire=now gc "$@"

L'option --agressive pourrait être utile.

NOTE : cette opération supprimera TOUS les éléments non référencés, alors ne venez pas pleurer si vous décidez plus tard que vous vouliez en garder certains !

Vous pourriez aussi avoir besoin d'exécuter quelque chose comme ceci d'abord, oh là là, git est compliqué !

git remote rm origin
rm -rf .git/refs/original/ .git/refs/remotes/ .git/*_HEAD .git/logs/
git for-each-ref --format="%(refname)" refs/original/ |
  xargs -n1 --no-run-if-empty git update-ref -d

J'ai mis tout ça dans un script, ici :

http://sam.nipl.net/b/git-gc-all-ferocious

2 votes

Comme dans stackoverflow.com/questions/1904860/ , +1 à vous encore.

25 votes

Excellent :D mon plan diabolique pour obtenir plus de points en clonant les réponses a fonctionné !1 ;)

0 votes

Oui ! Cela a fonctionné, mais j'ai dû exécuter le script complet. Exécuter seulement la commande gc (avec les options de configuration) n'était pas suffisant.

32voto

Josh Lee Points 53741

Votre git reflog expire --all est incorrect. Il supprime les entrées de reflog qui sont plus anciennes que le délai d'expiration, qui est de 90 jours par défaut. Utilisez git reflog expire --all --expire=now .

Ma réponse à une question similaire traite du problème du nettoyage réel des objets inutilisés d'un référentiel.

25voto

Jamie Points 21

1) Supprimez le fichier du dépôt git (et non du système de fichiers) :

  • git rm --cached path/to/file

2) Réduire le repo en utilisant :

  • git gc ,

  • o git gc --aggressive

  • o git prune

ou une combinaison de ces éléments, comme suggéré dans cette question : Réduire la taille du dépôt git

10voto

Daenyth Points 11297

Ce guide sur suppression des données sensibles peuvent s'appliquer, en utilisant la même méthode. Vous réécrirez l'historique pour supprimer ce fichier de chaque révision dans laquelle il était présent. Cette opération est destructive et provoquera des conflits de repo avec d'autres extractions, il faut donc en avertir les collaborateurs.

Si vous voulez garder le binaire disponible dans le dépôt pour d'autres personnes, il n'y a pas vraiment de moyen de faire ce que vous voulez. C'est à peu près tout ou rien.

9voto

La clé pour moi s'est avérée être de courir git repack -A -d -f et ensuite git gc pour réduire la taille de l'unique paquet git que j'avais.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X