J'ai accidentellement ajouté, validé et poussé un énorme fichier binaire avec mon tout dernier commit dans un référentiel Git.
Comment puis-je faire en sorte que Git supprime le ou les objets qui ont été / ont été créés pour ce commit afin que mon .git
répertoire redevienne à une taille raisonnable?
Edit : Merci pour vos réponses; J'ai essayé plusieurs solutions. Aucun n'a fonctionné. Par exemple, celui de GitHub a supprimé les fichiers de l'historique, mais la .git
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 :-(
git-repack -a
suivi pargit-prune-packed
exemple. Voir blog.felipebalbi.com/2007/12/19filter-branch
,gc
,repack
, ...), non, vous ne devriez pas voir une mauvaise commettre du tout. C'est un signe que le nettoyage n'a pas eu lieu comme prévu.Réponses:
J'ai répondu à cela ailleurs, et je vais copier ici puisque j'en suis fier!
... et sans plus tarder, puis-je vous présenter ce script utile, git-gc-all, garanti pour supprimer tous vos déchets git jusqu'à ce qu'ils puissent proposer 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 --aggressive peut être utile.
REMARQUE: cela supprimera TOUS les trucs non référencés, alors ne venez pas me pleurer si vous décidez plus tard que vous vouliez en garder certains!
Vous devrez peut-être également exécuter quelque chose comme ça en premier, oh mon Dieu, c'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
la source
xargs
commande produit une erreur sur OS X en raison d'une option non reconnue. Solution la plus simple: installez GNU xargs via homebrewbrew install findutils
et remplacez-lexargs
pargxargs
.Votre
git reflog expire --all
est incorrect. Il supprime les entrées de reflog qui sont plus anciennes que la date d'expiration, qui est par défaut de 90 jours. Utilisezgit reflog expire --all --expire=now
.Ma réponse à une question similaire traite du problème du nettoyage des objets inutilisés d'un référentiel.
la source
1) Supprimez le fichier du référentiel git (et non du système de fichiers):
git rm --cached path/to/file
2) Réduisez le repo en utilisant:
git gc
,ou
git gc --aggressive
git prune
ou une combinaison des éléments ci-dessus comme suggéré dans cette question: Réduisez la taille du référentiel git
la source
Ce guide sur la suppression des données sensibles peut s'appliquer, en utilisant la même méthode. Vous allez réécrire l'historique pour supprimer ce fichier de chaque révision dans laquelle il était présent. Ceci est destructeur et entraînera des conflits de dépôt avec toutes les autres extractions, donc avertissez d'abord les collaborateurs.
Si vous souhaitez 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.
la source
La clé pour moi s'est avérée être en cours d'exécution
git repack -A -d -f
et ensuitegit gc
réduire la taille du seul git pack que j'avais.la source
Hy!
Git ne reçoit que les objets dont il a réellement besoin lors du clonage de référentiels (si je comprends bien)
Vous pouvez donc modifier le dernier commit en supprimant le fichier ajouté par erreur, puis pousser vos modifications dans le référentiel distant (avec l'option -f pour écraser l'ancien commit sur le serveur également)
Ensuite, lorsque vous créez un nouveau clone de ce dépôt, son répertoire .git doit être aussi petit qu'avant la validation du ou des gros fichiers.
Si vous souhaitez également supprimer les fichiers inutiles du serveur, vous pouvez supprimer le référentiel sur le serveur et envoyer votre copie nouvellement clonée (qui a l'historique complet)
la source
Voir "Suppression d'objets" dans le livre Pro Git:
http://git-scm.com/book/en/Git-Internals-Maintenance-and-Data-Recovery#Removing-Objects
Mise à jour: voir aussi BFG repo cleaner: http://rtyley.github.io/bfg-repo-cleaner/
la source
N'oubliez pas de remplacer
Filename
celui que vous souhaitez supprimer du référentiel.la source
En 2020, la documentation de git-filter-branch décourage son utilisation et recommande d'utiliser une alternative telle que git-filter-repo . Il peut également être utilisé à la place de BFG .
Notez que le chapitre sur la réécriture de l'historique dans le livre git n'a pas été mis à jour. Ni a la recommandation de GitHub sur la suppression des données sensibles.
la source