Comment faire pour supprimer/supprimer un fichier volumineux à partir de commettre l'histoire dans le dépôt Git?
Parfois j'ai laissé tomber un DVD-rip dans un projet de site web, négligemment git commit -a -m ...
, et, zap, les pensions de titres a été gonflé par 2.2 concerts. La prochaine fois, j'ai fait quelques modifications, supprimé le fichier vidéo, et engage tout, mais le fichier compressé est toujours là dans le référentiel, dans l'histoire.
Je sais que je peux commencer les branches de ces validations et rebase une branche à l'autre. Mais que dois-je faire pour fusionner les 2 s'engage pour que les gros fichier n'apparaît pas dans l'histoire et ont été nettoyés dans la collecte des ordures procédure?
- Cet article devraient vous aider help.github.com/removing-sensitive-data
- Connexes: supprimer Complètement fichier de tous les dépôts Git commit l'histoire.
- Notez que si votre fichier de grande taille est dans un sous répertoire, vous devez spécifier le chemin d'accès relatif.
- connexes help.github.com/articles/...
- Également lié help.github.com/en/articles/...
Vous devez vous connecter pour publier un commentaire.
Utiliser le BFG Repo-Cleaner, plus simple, plus rapide, alternative à
git-filter-branch
spécialement conçu pour supprimer les fichiers d'historique de Git.Suivez attentivement les les instructions d'utilisation, la partie centrale est simplement ceci:
Tout les fichiers de plus de 100 mo (qui ne sont pas dans votre dernière commettre) sera supprimé de votre dépôt Git de l'histoire. Vous pouvez ensuite utiliser
git gc
pour nettoyer la mort des données:Le BFG est habituellement d'au moins 10-50x plus rapide que la course
git-filter-branch
, et généralement plus facile à utiliser.Divulgation complète: je suis l'auteur de la BFG Repo-Cleaner.
git push --force
après vos étapes, sinon la télécommande repo toujours pas changé.git push --force
. Aussi à noter: la force de pousse ne peut pas être admis par la télécommande (gitlab.com n'est pas, par défaut. Avait à "ôter la protection de" la branche).--strip-blobs-bigger-than 100M
vous pouvez également utiliser-b 100M
en fonction de l'aide.git reflog expire --expire-unreachable=all
comme décrit par @Greg Bacon dans sa réponse ici. Si il y a encore reflog les entrées, les données ne seront pas supprimés pargit gc
, même avecaggressive
(apparemment il y a des limites à son agressivité)git gc
sur la cible repo, puis exécutez de nouveau que ce que vous faisiez avec BFG. Une fois trié assez bien travaillé. Pourrait utiliser plus de documentation explicite, mais alors je ne suis pas le moyen le plus rapide de l'apprenant ;pbrew install bfg
me donneWarning: bfg 1.12.15 is already installed
ok:$ java -jar bfg.jar --strip-blobs-bigger-than 1M myrepo.git
j'obtiens:Error: Unable to access jarfile bfg.jar
does the repo need to be packed?
certainement, doivent être documentées.git reflog expire --expire=now --all && git gc --prune=now --aggressive
Ce que vous voulez faire est très perturbatrice si vous avez publié l'histoire à d'autres développeurs. Voir “La récupération De l'Amont Rebase” dans le
git rebase
de la documentation pour les mesures nécessaires après la réparation de votre histoire.Vous avez au moins deux options:
git filter-branch
et un rebase interactif, à la fois expliqués ci-dessous.À l'aide de
git filter-branch
J'ai eu un problème similaire avec les encombrants binaire des données de test à partir d'un import de Subversion et écrit à propos de suppression des données d'un dépôt git.
Dire que votre historique de git est:
Noter que
git lola
est un non-standard, mais très utile alias. Avec le--name-status
interrupteur, on peut voir l'arbre des modifications associées à chaque commit.Dans le “Négligent” commit (dont SHA1 nom de l'objet est ce36c98) le fichier
oops.iso
est le DVD-rip ajouté par accident et retiré dans le prochain commit, cb14efd. À l'aide de la technique décrite dans le blog précité, la commande à exécuter est:Options:
--prune-empty
supprime s'engage à ce que deviennent vides (c'est à dire, ne modifiez pas l'arbre) comme résultat de l'opération de filtrage. Dans le cas typique, cette option produit un nettoyeur de l'histoire.-d
noms un répertoire temporaire qui n'existe pas encore à utiliser pour la construction de l'filtré de l'histoire. Si vous êtes en cours d'exécution sur une distribution Linux moderne, la spécification d'un arbre dans/dev/shm
sera plus rapide d'exécution.--index-filter
est le principal événement et va à l'encontre de l'index à chaque étape de l'histoire. Vous souhaitez supprimeroops.iso
partout où il se trouve, mais il n'est pas présent dans tous les commits. La commandegit rm --cached -f --ignore-unmatch oops.iso
supprime le DVD-rip quand il est présent et ne manque pas autrement.--tag-name-filter
décrit comment réécrire les noms de balise. Un filtre decat
est l'identité de l'opération. Votre référentiel, comme l'exemple ci-dessus, peuvent ne pas avoir toutes les étiquettes, mais j'ai inclus cette option pour tous les cas.--
spécifie la fin des options degit filter-branch
--all
suivantes--
est un raccourci pour toutes les refs. Votre référentiel, comme l'exemple ci-dessus, ne peut avoir qu'un ref (master), mais j'ai inclus cette option pour tous les cas.Après quelques barattage, l'histoire est maintenant:
Avis que la nouvelle “Négligent” commettre ajoute seulement
other.html
et que le “Supprimer DVD-rip” commit n'est plus sur la branche master. La direction de la étiquetésrefs/original/refs/heads/master
contient votre original s'engage, dans le cas où vous faites une erreur. Pour l'enlever, suivez les étapes décrites dans “Liste de contrôle pour la réduction d'un Référentiel”.Pour une solution plus simple, cloner le dépôt débarrasser de l'indésirable bits.
À l'aide d'un
file:///...
clone URL copies des objets plutôt que de créer des liens physiques uniquement.Maintenant, votre histoire est:
Le SHA1 les noms d'objet pour les deux premiers commits (“Index” et “page d'administration”) est resté le même, parce que l'opération de filtrage ne modifiez pas ces validations. “Négligent” perdu
oops.iso
et “page de Connexion” vous avez un nouveau parent, de sorte que leur SHA1s ne changement.Rebase interactif
Avec une histoire de:
vous souhaitez supprimer
oops.iso
de “Négligent” comme si vous n'avez jamais ajouté, puis “Supprimer DVD-rip” est inutile pour vous. Ainsi, notre plan est d'entrer dans un rebase interactif est de garder “l'Admin de la page, puis” modifier “Négligents”, et jeter “Supprimer DVD-rip.”De course
$ git rebase -i 5af4522
commence un éditeur de texte avec le contenu suivant.L'exécution de notre plan, nous le modifier à
Qui est, nous supprimer la ligne avec “Supprimer DVD-rip” et de modifier l'opération sur le “Négligent” pour être
edit
plutôt quepick
.Enregistrez-la fermeture de l'éditeur de nous dépose à une invite de commandes avec le message suivant.
Que le message nous dit, nous sommes sur la “Négligent” engageons nous voulons modifier, afin de nous exécuter deux commandes.
La première supprime le fichier avi à partir de l'index. Le second modifie ou modifie “Négligent” à la mise à jour de l'index et
-C HEAD
indique à git pour réutiliser les vieux message de commit. Enfin,git rebase --continue
va de l'avant avec le reste de la rebase opération.Cela donne une histoire de:
qui est ce que vous voulez.
-f
(ou--force
) option pour votregit push
commande: “Généralement, la commande refuse de mettre à jour à distance ref qui n'est pas un ancêtre de la locale ref utilisé pour le remplacer. Ce drapeau désactive la vérification. Cela peut entraîner le dépôt distant à perdre s'engage; utiliser avec prudence.”... "git rm --cached -rf --ignore-unmatch path/to/dir"...
edit
et nettoyer à la main dans le shell.Pourquoi ne pas utiliser cette simple mais puissante de commande?
La
--tree-filter
option exécute la commande spécifiée après chaque checkout du projet, puis engage à nouveau les résultats. Dans ce cas, vous supprimez un fichier appelé DVD-rip de chaque photo, si elle existe ou pas.Voir ce lien.
fatal: bad revision 'rm'
, que j'ai fixé en utilisant"
au lieu de'
. Ensemble de commande:git filter-branch --force --index-filter "git rm --cached -r --ignore-unmatch oops.iso" --prune-empty --tag-name-filter cat -- --all
\
comme séparateur de chemin - être même sur Windows. J'ai eu à utiliser/
..git-rewrite
répertoire tout en gardant les fichiers supprimés dans le repo.commit
où vous placez le fichier dans (dire35dsa2
), vous pouvez remplacerHEAD
avec35dsa2..HEAD
.tree-filter
est beaucoup plus lent queindex-filter
que la façon dont il l'habitude d'essayer de les extraire tous les commits et les réécrire. si vous utilisez la TÊTE, il va essayer de le faire.(La meilleure réponse que j'ai vu à ce problème est: https://stackoverflow.com/a/42544963/714112 , copié ici depuis ce fil semble élevé dans les classements de recherche de Google, mais que d'autres n'en ont pas),
Extrêmement rapides shell one-liner
Ce script shell affiche tous les objets blob dans le référentiel, triées de la plus petite à la plus grande.
Pour mon exemple, repo, il a couru sur 100 fois plus rapide que les autres qui se trouvent ici.
Sur mon fidèle Athlon II X4 système, il gère le Noyau Linux référentiel avec ses 5,622,155 objets dans peu plus d'une minute.
La Base De Script
Lorsque vous exécutez le code ci-dessus, vous obtiendrez de nice lisible par l'homme de sortie comme ceci:
Rapide De Suppression De Fichiers
Supposons que vous souhaitez supprimer les fichiers
a
etb
de chaque livraison accessible à partir deHEAD
, vous pouvez utiliser cette commande:--tag-name-filter cat
de marquer de nouveau le nouveau correspondant, s'engage comme ils sont réécrits, c'est à dire,git filter-branch --index-filter 'git rm --cached --ignore-unmatch a b' --tag-name-filter cat HEAD
(voir cette réponse)git filter-branch --index-filter 'git rm --cached --ignore-unmatch <filename>' HEAD
l'ordre du travail droit de la chauve-sourisgit rev-list --objects --all \ | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \ | awk '/^blob/ {print substr($0,6)}' \ | sort --numeric-sort --key=2 \ | gnumfmt --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest
Ces commandes travaillé dans mon cas:
C'est un peu différent de versions ci-dessus.
Pour ceux qui en ont besoin pour pousser à l'github/bitbucket (j'ai uniquement testé avec bitbucket):
git rm --cached files
. Le Greg de Bacon proposition est plus complet, et tout à fait la même chose à cette mine, mais il a raté l' --l'indice de force pour les cas où vous utilisez filter-branch plusieurs fois, et il a écrit tellement d'infos, que ma version est comme le résumé d'elle.-f
option pas seulement-rf
icigit rm --cached -rf --ignore-unmatch oops.iso
au lieu degit rm --cached -r --ignore-unmatch oops.iso
comme par @lfender6445 ci-dessousAprès avoir essayé pratiquement toutes les réponses dans l'affirmative, j'ai enfin trouvé ce petit bijou qui permet d'éliminer rapidement et supprimé les fichiers de grande taille dans mon référentiel et m'a permis de synchroniser à nouveau: http://www.zyxware.com/articles/4027/how-to-delete-files-permanently-from-your-local-and-remote-git-repositories
CD à votre dossier de travail et exécutez la commande suivante:
remplacer le nom du DOSSIER avec le fichier ou le dossier que vous souhaitez supprimer à partir de la donnée du répertoire git.
Une fois cela fait, lancez les commandes suivantes pour nettoyer le dépôt local:
Maintenant pousser toutes les modifications sur le dépôt distant:
Ce sera de nettoyer le dépôt distant.
Il suffit de noter que ces commandes peuvent être très destructrices. Si plusieurs personnes travaillent sur le repo ils vont tous avoir à tirer de la nouvelle arborescence. Les trois du milieu commandes ne sont pas nécessaires si votre but n'est PAS de réduire la taille. Parce que le filtre de la branche crée une copie de sauvegarde du fichier supprimé et il peut y rester pendant une longue période.
git filter-branch --force --index-filter 'git rm --cached -r --ignore-unmatch oops.iso' --prune-empty --tag-name-filter cat -- --all
au lieu de la première un à partir de votre codegit filter-branch --tree-filter 'rm -f path/to/file' HEAD
a fonctionné assez bien pour moi, même si je suis dans la même situation que décrit ici, que j'ai résolu en suivant cette suggestion.
La pro-git livre a un chapitre entier sur les réécriture de l'histoire - avoir un regard sur le
filter-branch
/la Suppression d'un Fichier à partir de Chaque livraison section.Si vous savez que votre livraison récente au lieu de passer par l'ensemble de l'arborescence effectuer les opérations suivantes:
git filter-branch --tree-filter 'rm LARGE_FILE.zip' HEAD~10..HEAD
J'ai couru ce avec un compte bitbucket, où j'avais accidentellement stockées ginormous *.jpa sauvegardes de mon site.
git filter-branch --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch MY-BIG-DIRECTORY-OR-FILE' --tag-name-filter cat -- --all
Relpace
MY-BIG-DIRECTORY
avec le dossier en question de réécrire complètement votre histoire (y compris les balises).source: http://naleid.com/blog/2012/01/17/finding-and-purging-big-files-from-git-history
Vous pouvez faire cela en utilisant la
branch filter
commande:git filter-branch --tree-filter 'rm -rf path/to/your/file' HEAD
En gros, j'ai fait ce qui était sur cette réponse:
https://stackoverflow.com/a/11032521/1286423
(pour l'histoire, je vais le copier-coller ici)
Il n'a pas de travail, parce que je tiens à renommer et déplacer des choses beaucoup. De sorte que certains gros dossiers dans des dossiers qui ont été renommés, et je pense que le gc ne pouvais pas supprimer la référence à ces fichiers car de référence dans
tree
objets pointant vers ces fichiers.Mon ultime solution pour vraiment tuer c'était:
Mon repo (le
.git
) a changé de 32 MO à 388KB, que même filter-branch ne pouvais pas la nettoyer.Utilisation Git Extensions, c'est une INTERFACE utilisateur de l'outil. Il a un plugin nommé "Trouver les gros fichiers" qui se retrouve lage des fichiers dans des référentiels et permettre de retirer leur permenently.
Ne pas utiliser git filter-branch' avant d'utiliser cet outil, car il ne sera pas en mesure de trouver les fichiers supprimés par "filter-branch' (Barbante 'filter-branch' ne supprime pas les fichiers complètement à partir du référentiel de fichiers de pack).
Quand vous avez ce problème,
git rm
ne suffira pas, comme git se souvient que le fichier existait autrefois dans notre histoire, et donc de conserver une référence à elle.Pour aggraver les choses, la relocalisation n'est pas facile, parce que de toute référence à la goutte permettra d'éviter git garbage collector de nettoyage de l'espace. Cela comprend les références à distance et reflog références.
J'ai mis en place
git forget-blob
, un petit script qui tente de retirer toutes ces références, puis utilise git filter-branch à réécrire chaque commit de la branche.Une fois votre blob est complètement non référencées,
git gc
va se débarrasser de celaL'utilisation est assez simple
git forget-blob file-to-forget
. Vous pouvez obtenir plus d'info icihttps://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-forget-blob/
J'ai mis cela ensemble grâce aux réponses de Débordement de Pile et certains entrées de blog. Des crédits afin de!
git filter-branch
est une commande puissante que vous pouvez utiliser pour supprimer un fichier énorme de la commet l'histoire. Le fichier va rester pendant un certain temps et Git supprime dans la prochaine collecte de déchets.Ci-dessous est le processus complet de deleteing des fichiers à partir de commettre l'histoire. Pour plus de sécurité, il est d'abord exécuter la commande sur une nouvelle branche: