Supprimer le dossier et son contenu de l'historique de git/GitHub

je travaillais sur un dépôt sur mon compte GitHub et c'est un problème que j'ai rencontré.

  • Node.projet js avec un dossier avec quelques paquets npm installés
  • les colis étaient dans node_modules dossier
  • a ajouté ce dossier au dépôt git et a poussé le code sur github (ne pensait pas à la partie npm à ce moment-là)
  • réalisé que vous n'avez pas vraiment besoin de ce dossier pour être une partie du code
  • a supprimé ce dossier, l'a poussé

à cette occasion, la taille de la Git totale repo était d'environ 6MB où le code réel (tous sauf ce dossier) était seulement d'environ 300 KB .

maintenant ce que je cherche à la fin est un moyen de se débarrasser des détails de ce dossier paquet de l'histoire de git donc si quelqu'un le clone, ils n'ont pas à télécharger 6mb valeur de l'histoire où les seuls dossiers réels qu'ils obtiendront à partir de la dernière commit serait 300KB.

j'ai cherché des solutions possibles pour cela et essayé ces 2 méthodes

l'essentiel semblait fonctionner là où après l'exécution du script, il a montré qu'il s'était débarrassé de ce dossier et après cela il a montré que 50 propagations différentes ont été modifiées. Mais il ne m'a pas laissé pousser ce code. Quand j'ai essayé de le pousser, il a dit Branch up to date mais a montré 50 commits ont été modifiés sur un git status . Les deux autres méthodes n'ont pas aidé non plus.

maintenant même si elle a montré qu'il s'est débarrassé de l'histoire de ce dossier, quand je j'ai vérifié la taille de ce repo sur mon localhost, il était encore aux alentours de 6MB. (J'ai aussi supprimé le dossier refs/original mais je n'ai pas vu le changement dans la taille de la pension).

ce que je cherche à clarifier est, s'il y a un moyen de se débarrasser non seulement de l'historique de propagation (qui est la seule chose que je pense qu'il s'est passé), mais aussi ces fichiers git continue à supposer que l'on veut faire machine arrière.

disons qu'une solution est présentée pour cela et est appliquée sur mon hôte local mais ne peut être reproduit à ce repo GitHub, est-il possible de cloner que repo, rollback to the first commit effectuer le tour et le pousser (ou cela signifie-t-il que git aura toujours une histoire de tous ces commits? - aka. 6MB).

mon objectif final ici est de trouver la meilleure façon de se débarrasser du contenu du dossier de git afin qu'un utilisateur n'ait pas à télécharger 6MB de trucs et avoir encore éventuellement l'autre commits qui n'a jamais touché le dossier modules (c'est assez la plupart d'entre eux) dans l'histoire de git.

Comment faire?

204
demandé sur Community 2012-04-09 04:58:05

6 réponses

si vous êtes ici pour copier-coller le code:

Ceci est un exemple qui supprime node_modules de l'histoire

git filter-branch --tree-filter 'rm -rf node_modules' --prune-empty HEAD
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
echo node_modules/ >> .gitignore
git add .gitignore
git commit -m 'Removing node_modules from git history'
git gc
git push origin master --force
375
répondu Mohsen 2016-06-01 03:05:45

je trouve que l'option --tree-filter utilisée dans d'autres réponses peut être très lente, en particulier sur des dépôts plus grands avec beaucoup de propagations.

Voici la méthode que j'utilise pour supprimer complètement un répertoire de l'historique git en utilisant l'option --index-filter , qui s'exécute beaucoup plus rapidement:

# Make a fresh clone of YOUR_REPO
git clone YOUR_REPO
cd YOUR_REPO

# Create tracking branches of all branches
for remote in `git branch -r | grep -v /HEAD`; do git checkout --track $remote ; done

# Remove DIRECTORY_NAME from all commits, then remove the refs to the old commits
# (repeat these two commands for as many directories that you want to remove)
git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch DIRECTORY_NAME/' --prune-empty --tag-name-filter cat -- --all
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d

# Ensure all old refs are fully removed
rm -Rf .git/logs .git/refs/original

# Perform a garbage collection to remove commits with no refs
git gc --prune=all --aggressive

# Force push all branches to overwrite their history
# (use with caution!)
git push origin --all --force
git push origin --tags --force

vous pouvez vérifier la taille du dépôt avant et après le gc avec:

git count-objects -vH
138
répondu Lee Netherton 2016-12-29 11:17:58

En plus de la réponse au-dessus je voudrais ajouter quelques notes pour Windows -systèmes. La commande

git filter-branch --tree-filter 'rm -rf node_modules' --prune-empty HEAD
  • fonctionne parfaitement sans aucune modification ! Par conséquent, vous ne devez pas utiliser Remove-Item , del ou toute autre chose au lieu de rm -rf .

  • si vous besoin de spécifier un chemin d'accès à un fichier ou d'un répertoire d'utilisation slash comme ./path/to/node_modules

23
répondu participant 2017-05-23 12:10:48

la meilleure méthode et la plus précise que j'ai trouvé était de télécharger le bfg.fichier jar: https://rtyley.github.io/bfg-repo-cleaner /

puis lancez les commandes:

git clone --bare https://project/repository project-repository
cd project-repository
java -jar bfg.jar --delete-folders node_modules
git reflog expire --expire=now --all && git gc --prune=now --aggressive
git push --mirror https://project/new-repository

si vous voulez supprimer des fichiers, utilisez l'option Supprimer-fichiers à la place:

java -jar bfg.jar --delete-files *.pyc
10
répondu Kim T 2017-01-30 19:05:40

recette complète de copier-coller, en ajoutant simplement les commandes dans les commentaires( pour la solution de copier-coller), après les avoir testées:

git filter-branch --tree-filter 'rm -rf node_modules' --prune-empty HEAD
echo node_modules/ >> .gitignore
git add .gitignore
git commit -m 'Removing node_modules from git history'
git gc
git push origin master --force

Après cela, vous pouvez supprimer la ligne "node_modules/".gitignore

5
répondu jgbarah 2015-01-22 18:12:34

j'ai supprimé les dossiers bin et obj des anciens projets C# en utilisant git sur windows. Attention avec

git filter-branch --tree-filter "rm -rf bin" --prune-empty HEAD

il détruit l'intégrité de l'installation git en supprimant le dossier usr/bin dans le dossier git install.

1
répondu LordObi 2018-01-04 21:58:27