161 votes

Git : Comment supprimer un fichier d'un commit historique ?

J'ai un commit avec l'id 56f06019 (par exemple). Dans ce commit, j'ai accidentellement commité un gros fichier (50Mb). Dans un autre commit j'ai ajouté le même fichier mais dans la bonne taille (petit). Maintenant mon repo est trop lourd lorsque je le clone :( Comment supprimer ce gros fichier de l'historique du repo pour réduire la taille de mon repo ?

0 votes

Dans mon cas, il ne s'agit pas d'un gros fichier, mais d'un fichier de configuration contenant les crédits de la base de données. J'étudiais git, à l'époque je n'étais pas au courant de .gitignore.

1 votes

218voto

sehe Points 123151

Le chapitre 9 de la Pro Git Le livre contient une section sur Suppression d'objets .

Permettez-moi de vous présenter brièvement ces étapes :

git filter-branch --index-filter \
    'git rm --cached --ignore-unmatch path/to/mylarge_50mb_file' \
    --tag-name-filter cat -- --all

Comme l'option de rebasement décrite précédemment, filter-branch est une opération de réécriture. Si vous avez un historique publié, vous devrez --force pousser les nouveaux arbitres.

El filter-branch est considérablement plus puissante que l'approche rebase l'approche, car elle

  • vous permet de travailler sur toutes les branches/réflexions en même temps,
  • renomme les balises à la volée
  • fonctionne proprement même s'il y a eu plusieurs commits de fusion depuis l'ajout du fichier
  • fonctionne proprement même si le fichier a été (ré)ajouté/supprimé plusieurs fois dans l'histoire d'une (des) branche(s)
  • ne crée pas de nouveaux commits sans rapport, mais les copie plutôt en modifiant les arbres qui leur sont associés. Cela signifie que des choses comme les commits signés, les notes de commit, etc. sont préservées.

filter-branch conserve également des sauvegardes, de sorte que la taille du dépôt ne diminuera pas immédiatement à moins que vous n'expiriez les reflogs et le garbage collect :

rm -Rf .git/refs/original       # careful
git gc --aggressive --prune=now # danger

1 votes

Il est intéressant de noter que cela ne semble pas fonctionner sous Windows cmd.exe. Il semble que cela fonctionne bien sous Cygwin, cependant.

2 votes

J'ai réussi à faire fonctionner la branche de filtrage git ci-dessus en utilisant des guillemets doubles au lieu de guillemets simples (sur Windows Server 2012 cmd.exe).

2 votes

Ce qui a fonctionné pour moi est cette ligne de commande filter-branch. git filter-branch --force --index-filter 'git rm --ignore-unmatch --cached PathTo/MyFile/ToRemove.dll' -- fbf28b005^.. Puis rm --recursive --force .git/refs/original y rm --recursive --force .git/logs Ensuite, j'ai utilisé le git prune --expire now y git gc --aggressive Cela a mieux fonctionné pour moi que vos étapes exactes énumérées ci-dessus. Merci d'avoir inclus le lien vers le livre Git Pro, qui m'a été très utile.

23voto

Ofer Segev Points 131

Vous pouvez utiliser git-extras outil. Le site anéantir supprime complètement un fichier du référentiel, y compris les commits et les tags passés.

https://github.com/tj/git-extras/blob/master/Commands.md

2 votes

Génial ! Cela a fait le travail. Si merveilleusement simple.

0 votes

Merci beaucoup pour cette solution si merveilleuse et si simple.

9voto

Sandeep Dixit Points 164

J'ai essayé d'utiliser la réponse suivante sous Windows https://stackoverflow.com/a/8741530/8461756

Les guillemets simples ne fonctionnent pas sous Windows ; il faut des guillemets doubles.

Ce qui suit a fonctionné pour moi.

git filter-branch --force --index-filter "git rm --cached --ignore-unmatch PathRelativeRepositoryRoot/bigfile.csv" -- --all

Après avoir supprimé le gros fichier, j'ai pu pousser mes changements vers le master GitHub.

1voto

Vous devrez git rebasement en mode interactif, voir un exemple ici : Comment supprimer un commit sur GitHub ? y comment supprimer les anciens commits .

Si votre commit est à HEAD moins 10 commits :

$ git rebase -i HEAD~10

Après l'édition de votre historique, vous devez pousser le "nouvel" historique, vous devez ajouter l'icône de l'historique. + à forcer (voir la spécification de référence dans le fichier options de poussée ) :

$ git push origin +master

Si d'autres personnes ont déjà cloné votre dépôt, vous devez les en informer, car vous venez de modifier l'historique.

4 votes

Cela fait no supprimer le fichier volumineux de l'historique. Aussi, la façon canonique de forcer le push est git push --force o git push -f (ce qui ne nécessite pas que les gens connaissent la cible de la poussée de branche)

0 votes

D'après la question, le nouveau fichier est exactement le même que l'ancien, c'est-à-dire qu'il a le même chemin. C'est pourquoi vous ne pouvez pas utiliser directement git rm sur le chemin.

2 votes

@sehe, si vous faites un rebase éliminant le commit avec l'énorme fichier, il est parti pour de bon.

-1voto

mini developer Points 154

Vous pouvez utiliser une simple commande pour supprimer

 git rm -r -f app/unused.txt 
 git rm -r -f yourfilepath

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