(résolu, voir le bas du corps de la question)
Vous cherchez cela depuis longtemps maintenant, ce que j'ai jusqu'à présent est:
À peu près la même méthode, mais les deux laissent des objets dans les fichiers de pack ... Coincé.
Ce que j'ai essayé:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_name'
rm -Rf .git/refs/original
rm -Rf .git/logs/
git gc
Il y a toujours des fichiers dans le pack, et voici comment je le sais:
git verify-pack -v .git/objects/pack/pack-3f8c0...bb.idx | sort -k 3 -n | tail -3
Et ça:
git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch file_name" HEAD
rm -rf .git/refs/original/ && git reflog expire --all && git gc --aggressive --Prune
Le même...
A tenté git clone
astuce, il a supprimé certains fichiers (~ 3000 d'entre eux) mais les plus gros fichiers sont toujours là ...
J'ai de gros fichiers hérités dans le référentiel, ~ 200M, et je ne veux vraiment pas qu'ils y soient ... Et je ne veux pas réinitialiser le référentiel à 0 :(
SOLUTION: C'est le moyen le plus court de se débarrasser des fichiers:
refs/remotes/Origin/master
ligne pour un dépôt distant, supprimez-le, sinon git ne supprimera pas ces fichiersgit verify-pack -v .git/objects/pack/#{pack-name}.idx | sort -k 3 -n | tail -5
- pour rechercher les fichiers les plus volumineuxgit rev-list --objects --all | grep a0d770a97ff0fac0be1d777b32cc67fe69eb9a98
- pour vérifier quels sont ces fichiersgit filter-branch --index-filter 'git rm --cached --ignore-unmatch file_names'
- pour supprimer un fichier de toutes les révisionsrm -rf .git/refs/original/
- pour supprimer la sauvegarde de gitgit reflog expire --all --expire='0 days'
- pour expirer tous les objets en vracgit fsck --full --unreachable
- pour vérifier s'il y a des objets en vracgit repack -A -d
- reconditionnementgit Prune
- pour enfin supprimer ces objetsJe ne peux pas dire avec certitude sans accès à vos données de référentiel, mais je pense qu'il y a probablement une ou plusieurs références compressées faisant toujours référence à d'anciennes validations avant d'exécuter git filter-branch
. Cela expliquerait pourquoi git fsck --full --unreachable
n'appelle pas le gros blob un objet inaccessible, même si vous avez expiré votre reflog et supprimé les références d'origine (décompressées).
Voici ce que je ferais (après git filter-branch
et git gc
ont été fait):
1) Assurez-vous que les références d'origine ont disparu:
rm -rf .git/refs/original
2) Expire toutes les entrées de reflog:
git reflog expire --all --expire='0 days'
) Vérifiez les anciennes références emballées
Cela pourrait être délicat, selon le nombre de références emballées dont vous disposez. Je ne connais aucune commande Git qui automatise cela, donc je pense que vous devrez le faire manuellement. Faites une sauvegarde de .git/packed-refs
. Maintenant éditez .git/packed-refs
. Vérifiez les anciennes références (en particulier, voyez si elles contiennent toutes les références de .git/refs/original
). Si vous en trouvez d'anciens qui n'ont pas besoin d'être là, supprimez-les (supprimez la ligne de cette référence).
Après avoir nettoyé le packed-refs
fichier, voir si git fsck
remarque les objets inaccessibles:
git fsck --full --unreachable
Si cela a fonctionné, et git fsck
signale maintenant que votre gros blob est inaccessible, vous pouvez passer à l'étape suivante.
4) Remballez vos archives emballées
git repack -A -d
Cela garantira que les objets inaccessibles seront décompressés et rester décompressés.
5) Taillez les objets lâches (inaccessibles)
git Prune
Et cela devrait le faire. Git devrait vraiment avoir une meilleure façon de gérer les refs emballés. Il y a peut-être une meilleure façon que je ne connais pas. En l'absence d'une meilleure méthode, l'édition manuelle du packed-refs
le fichier est peut-être la seule solution.
Je recommanderais d'utiliser BFG Repo-Cleaner , une alternative plus simple et plus rapide à git-filter-branch
spécialement conçu pour réécrire des fichiers de l'historique Git. Une façon de vous faciliter la vie ici est qu'il gère en fait tous références par défaut (toutes les balises, les branches, des trucs comme refs/remotes/Origin/master, etc.) mais c'est aussi - 10-50x plus rapide.
Vous devez suivre attentivement ces étapes ici: http://rtyley.github.com/bfg-repo-cleaner/#usage - mais le bit de base est juste ceci: téléchargez le pot de BFG (nécessite Java 6 ou supérieur) et exécutez cette commande:
$ Java -jar bfg.jar --delete-files file_name my-repo.git
Tout fichier nommé file_name
(qui n'est pas dans votre dernier commit) sera totalement supprimé de l'historique de votre référentiel. Vous pouvez ensuite utiliser git gc
pour nettoyer les données mortes:
$ git gc --Prune=now --aggressive
Le BFG est généralement beaucoup plus simple à utiliser que git-filter-branch
- les options sont adaptées à ces deux cas d'utilisation courants:
Divulgation complète: je suis l'auteur du BFG Repo-Cleaner.
J'ai trouvé cela très utile en ce qui concerne la suppression d'un dossier entier car ce qui précède ne m'a pas vraiment aidé: https://help.github.com/articles/remove-sensitive-data .
J'ai utilisé:
git filter-branch -f --force \
--index-filter 'git rm -rf --cached --ignore-unmatch folder/sub-folder' \
--Prune-empty --tag-name-filter cat -- --all
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --Prune=now
git gc --aggressive --Prune=now
J'essayais de me débarrasser d'un gros fichier dans l'histoire, et les réponses ci-dessus ont fonctionné, jusqu'à un certain point. Le point est: ils ne fonctionnent pas si vous avez des balises. Si la validation contenant le gros fichier est accessible à partir d'une balise, vous devrez alors ajuster la commande filter-branches:
git filter-branch --tag-name-filter cat \
--index-filter 'git rm --cached --ignore-unmatch huge_file_name' -- \
--all --tags
Voir: Comment supprimer des fichiers sensibles de l'historique de git
Ce qui précède échouera si le fichier n'existe pas dans une rév. Dans ce cas, le commutateur '--ignore-unmatch' le corrigera:
git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch <filename>' HEAD
Ensuite, pour retirer tous les objets en vrac de la reposition:
git gc --Prune='0 days ago'
Vous avez plusieurs raisons pour une taille de référentiel git encore grande après git gc
, car il ne supprime pas tous les objets libres .
Je détaille ces raisons dans " réduire la taille du dépôt git "
Mais une astuce à tester dans votre cas serait de cloner votre dépôt Git "nettoyé" et voir si le clone a le taille appropriée.
("repo" nettoyé "" étant celui où vous avez appliqué le filter-branch
, puis gc
et Prune
)
Cela devrait être couvert par le git obliterate
commande dans Git Extras ( https://github.com/visionmedia/git-extras ).
git obliterate <filename>
J'ai eu le même problème et j'ai trouvé un excellent tutoriel sur github qui explique étape par étape comment se débarrasser des fichiers que vous avez accidentellement commis.
Voici un petit résumé de la procédure comme l'a suggéré Cupcake.
Si vous avez un fichier nommé file_to_remove
à supprimer de l'historique:
cd path_to_parent_dir
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch file_to_remove' \
--Prune-empty --tag-name-filter cat -- --all