229 votes

Comment réduire le dossier .git

Ma base actuelle a une taille totale d'environ 200 Mo.

Mais mon dossier .git a une taille incroyable de 5 Go ( !). Comme je pousse mon travail vers un serveur externe, je n'ai pas besoin d'un gros historique local...

Comment puis-je réduire le dossier .git pour libérer de l'espace sur mon ordinateur portable ? Puis-je supprimer toutes les modifications qui datent de plus de 30 jours ?

Merci beaucoup pour toute aide :)

2 votes

Pouvez-vous afficher la sortie de git count-objects -v ?

4 votes

Duplicata possible de Réduire la taille du dépôt git

0 votes

Mon problème était git lfs prenait des tonnes d'espace dans le .git/lfs dir. En exécutant git lfs prune J'ai réduit mon .git taille du dossier par >60 GO ! J'ai ajouté ces informations et d'autres encore dans ma réponse ici .

181voto

knittl Points 64110

Vous ne devez pas supprimer toutes les modifications datant de plus de 30 jours (je pense que c'est possible en exploitant git, mais ce n'est vraiment pas recommandé).

vous pouvez appeler git gc --aggressive --prune Vous avez beaucoup de fichiers binaires (archives, images, exécutables) qui changent souvent ? Ceux-ci conduisent généralement à des dossiers .git énormes (rappelez-vous que git stocke des instantanés pour chaque révision et que les fichiers binaires se compressent mal).

58 votes

En fait, git gc --aggressive est considéré comme une mauvaise pratique. Il est préférable d'utiliser git repack -a -d --depth=250 --window=250 .

0 votes

@artefact2 : c'est le cas ? git gc appelle repack en interne, donc je ne suis pas d'accord avec vous. avez-vous un lien pour étayer votre affirmation ?

0 votes

C'est un projet web avec beaucoup de php, js, css, et bien sûr des images :) je vais lancer git gc --aggressive --prue

104voto

David Dehghan Points 1047

Voici ce que le créateur de git Linus a à dire sur la façon de réduire votre repo git :

L'équivalent de "git gc --agressif" - mais fait *correctement* - est de faire (pendant la nuit) quelque chose comme

   git repack -a -d --depth=250 --window=250

où ce truc de profondeur est juste à propos de la profondeur des chaînes delta. (faites-les plus longues pour l'histoire ancienne - cela vaut la peine de gagner de l'espace), et la fenêtre concerne la taille de la fenêtre d'objet que nous voulons que chaque candidat delta doit scanner.

Et ici, vous pouvez ajouter l'option "-f" (qui est l'option "drop all"). anciens deltas ", puisque vous essayez maintenant de vous assurer que celui-ci trouve réellement de bons candidats.

source : http://gcc.gnu.org/ml/gcc/2007-12/msg00165.html

Cela permettra-t-il de se débarrasser des données binaires qui sont orphelines dans mon repo ? "git repack" ne se débarrassera pas des images ou des données binaires que vous avez enregistrées dans votre repo puis supprimées. Pour supprimer définitivement ce type de données de votre dépôt, vous devez réécrire votre historique. Un exemple courant de cela est lorsque vous enregistrez accidentellement vos mots de passe dans git. Vous pouvez revenir en arrière et supprimer certains fichiers, mais vous devez alors réécrire votre historique de l'époque à aujourd'hui, puis pousser de force le nouveau repo vers votre origine.

0 votes

Pour moi, le dossier .git pèse environ 1,5 G. J'ai essayé, mais j'ai eu l'erreur suivante. fatal: Out of memory, malloc failed (tried to allocate 39763130 bytes)

6 votes

Après avoir exécuté repack localement, en faisant un commit et un push, est-ce que le psy sera aussi fait à distance ?

0 votes

@David Dehghan : Hé, j'ai essayé depuis le répertoire du projet mais la taille du dossier .git n'a pas changé. Est-ce attendu, ou dois-je pousser pour voir les changements ? (Désolé, je n'ai pas beaucoup d'expérience avec git.) J'ai une image/gif dans le repo et j'ai commis plusieurs fois différentes versions de cette image et je suppose que cela a augmenté la taille de .git.

48voto

Chris Hinshaw Points 2109

Je les ai essayés, mais mon dépôt était encore très grand. Le problème était que j'avais accidentellement enregistré des fichiers volumineux générés. Après quelques recherches, j'ai trouvé un excellent tutoriel qui permet de supprimer facilement les gros fichiers générés. Ce tutoriel m'a permis de réduire mon référentiel de 60 Mo à < 1 Mo.

Steve Lorek, Comment réduire un dépôt Git ?

Mise à jour : Voici une version copier-coller de l'article de blog.

Comment réduire un dépôt Git ?

La taille de notre dépôt Git principal avait soudainement explosé. Il était passé en une nuit à 180 Mo (compressé) et prenait une éternité à cloner.

La raison était évidente ; quelqu'un, quelque part, avait commis des fichiers massifs. Mais nous n'avions aucune idée de ce qu'étaient ces fichiers.

Après quelques heures d'essais, d'erreurs et de recherches, j'ai réussi à mettre au point un processus :

  • Découvrez les grands dossiers
  • Nettoyez-les du référentiel
  • Modifier le dépôt distant (GitHub) pour que les fichiers ne soient plus jamais téléchargés

Ce processus ne doit jamais être tenté, sauf si vous pouvez garantir que tous les membres de l'équipe peuvent produire un nouveau clone. Il implique la modification de l'historique et exige que toute personne contribuant au dépôt retire le dépôt nouvellement nettoyé avant d'y pousser quoi que ce soit.

Clone profond du référentiel

Si vous n'avez pas encore de clone local du référentiel en question, créez-en un maintenant :

git clone remote-url

Maintenant, vous avez peut-être cloné le référentiel, mais vous n'avez pas toutes les branches distantes. C'est impératif pour assurer un bon "nettoyage en profondeur". Pour ce faire, nous aurons besoin d'un petit script en Bash :

#!/bin/bash
for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master`; do
    git branch --track ${branch##*/} $branch
done

Merci à bigfish sur StackOverflow pour ce script, qui est copié mot à mot.

Copiez ce code dans un fichier, chmod +x filename.sh et l'exécuter ensuite avec ./filename.sh . Vous aurez maintenant toutes les branches distantes également (c'est dommage que Git ne fournisse pas cette fonctionnalité).

Découvrir les gros fichiers

Le crédit est dû à Antony Stubbs ici - e script de Bash identifie les plus gros fichiers d'un dépôt Git local, et est reproduit textuellement ci-dessous :

#!/bin/bash
#set -x 

# Shows you the largest objects in your repo's pack file.
# Written for osx.
#
# @see http://stubbisms.wordpress.com/2009/07/10/git-script-to-show-largest-pack-objects-and-trim-your-waist-line/
# @author Antony Stubbs

# set the internal field spereator to line break, so that we can iterate easily over the verify-pack output
IFS=$'\n';

# list all objects including their size, sort by size, take top 10
objects=`git verify-pack -v .git/objects/pack/pack-*.idx | grep -v chain | sort -k3nr | head`

echo "All sizes are in kB. The pack column is the size of the object, compressed, inside the pack file."

output="size,pack,SHA,location"
for y in $objects
do
    # extract the size in bytes
    size=$((`echo $y | cut -f 5 -d ' '`/1024))
    # extract the compressed size in bytes
    compressedSize=$((`echo $y | cut -f 6 -d ' '`/1024))
    # extract the SHA
    sha=`echo $y | cut -f 1 -d ' '`
    # find the objects location in the repository tree
    other=`git rev-list --all --objects | grep $sha`
    #lineBreak=`echo -e "\n"`
    output="${output}\n${size},${compressedSize},${other}"
done

echo -e $output | column -t -s ', '

Exécutez ce script comme précédemment, et vous verrez une sortie similaire à celle ci-dessous :

All sizes are in kB. The pack column is the size of the object, compressed, inside the pack file.

size     pack    SHA                                       location
1111686  132987  a561d25105c79aa4921fb742745de0e791483afa  08-05-2012.sql
5002     392     e501b79448b9e970ab89b048b3218c2853fdfc88  foo.sql
266      249     73fa731bb90b04dcf79eeea8fdd637ba7df4c089  app/assets/images/fw/iphone.fw.png
265      43      939b31c563bd40b1ca70e4f4a9f7d67c27c936c0  doc/models_complete.svg
247      39      03514d9e84418573f26b205bae7e4e57057c036f  unprocessed_email_replies.sql
193      49      6e601c4067aaddb26991c4bd5fbddef003800e70  public/assets/jquery-ui.min-0424e108178defa1cc794ee24fc92d24.js
178      30      c014b20b6fed9f17a0b2809ac410d74f291da26e  foo.sql
158      158     15f9e56bc0865f4f303deff053e21909661a716b  app/assets/images/iphone.png
103      36      3135e15c5cec75a4c85a0636b154b83221020c97  public/assets/application-c65733a4a64a1a885b1c32694574b12a.js
99       85      c1c80bc4c09e692d5e2127e39c87ecacdb1e816f  app/assets/images/fw/lovethis_logo_sprint.fw.png

Oui, on dirait que quelqu'un a poussé des fichiers inutiles quelque part ! Y compris un joli 1.1GB présent sous la forme d'un fichier de vidage SQL.

Nettoyage des fichiers

Le nettoyage du fichier prendra un certain temps, en fonction de l'activité de votre dépôt. Vous avez juste besoin d'une commande pour commencer le processus :

git filter-branch --tag-name-filter cat --index-filter 'git rm -r --cached --ignore-unmatch filename' --prune-empty -f -- --all

Cette commande est adaptée d'autres sources - le principal ajout est le suivant --tag-name-filter cat ce qui garantit que les balises sont également réécrites.

Après l'exécution de cette commande, votre dépôt devrait maintenant être nettoyé, avec toutes les branches et balises intactes. Récupérer de l'espace

Nous avons peut-être réécrit l'histoire du dépôt, mais ces fichiers existent toujours, ils volent de l'espace disque et sont généralement nuisibles. Supprimons ces bâtards :

rm -rf .git/refs/original/

git reflog expire --expire=now --all

git gc --prune=now

git gc --aggressive --prune=now

Maintenant nous avons un dépôt frais et propre. Dans mon cas, il est passé de 180MB à 7MB.

Pousser le référentiel nettoyé

Nous devons maintenant pousser les changements vers le dépôt distant, afin que personne d'autre ne subisse la douleur d'un téléchargement de 180 Mo.

git push origin --force --all

El --all argument pousse toutes vos branches aussi bien. C'est pourquoi nous avions besoin de les cloner au début du processus.

Puis poussez les balises nouvellement réécrites :

git push origin --force --tags

Dites à vos coéquipiers

Toute autre personne disposant d'un clone local du référentiel devra utiliser soit git rebase ou créez un nouveau clone, sinon lorsqu'ils poussent à nouveau, ces fichiers seront poussés en même temps et le référentiel sera remis dans l'état dans lequel il était auparavant.

4 votes

Voici une version archivée en cas de rotation du lien. Cette réponse est/était utile pour un repo que j'ai rencontré où des fichiers .exe et .zip ont été livrés, ce qui a gonflé la taille du dossier .git.

0 votes

Une idée de la raison pour laquelle cela ne fonctionnerait pas ? Les mêmes gros fichiers existent après avoir suivi toutes ces étapes. Après la première commande de nettoyage (git filter-branch...), il y a un avertissement pour chaque branche indiquant qu'elle n'a pas été modifiée. J'utilise Git bash pour Windows si cela a de l'importance.

0 votes

Merci pour cette réponse. J'ai essayé cela sur mon repo et la taille du repo semble avoir diminué et il est évident aussi que le clone git est beaucoup plus rapide maintenant. Cependant, sur la page web de mon repo gitlab, la taille par rapport au stockage est toujours aussi grande que précédemment. 1 Commit 2 Branches 2 Tags 203.9 MB Files 203.9 MB Storage 2 Releases

14voto

Gabriel Staples Points 1804

Comment réduire votre dossier .git dans votre dépôt git ?

TLDR ;

Faites, dans cet ordre, du moins dangereux et/ou du plus efficace et/ou du plus rapide au plus dangereux et/ou au moins efficace et/ou au plus lent :

Ces résultats de test sont pour un repo où du -hs --exclude=.git . montre que la taille totale du repo, N'incluant PAS les .git dir, c'est à propos 80 GO y du -hs .git a montré que le .git dossier seul a commencé à environ 162 GB :

#                                                                   Memory Saved
#                                               Time it took        in .git dir
#                                               ------------        ------------
time git lfs prune                              #  1~60 min          62 GB
time git gc                                     #  3 min            < 1 GB
time git prune                                  #  1 min            < 1 GB
time git repack -a -d --depth=250 --window=250  #  2 min            < 1 GB
time git gc --aggressive --prune                #  1.25 hrs         < 1 GB

Comme vous pouvez le voir, la dernière commande prend une très longtemps pour très peu d'avantages, alors ne l'utilisez même pas !

Détails

Tout d'abord, vous devez savoir ce qui, dans le dossier .git, prend tant d'espace. Une technique consiste à lancer le programme ncurses-base (de type GUI) ncdu (NCurses Disk Usage) dans votre repo. Une autre façon est d'exécuter ceci :

du -h --max-depth=1 .git

Note complémentaire : Pour voir la taille de votre repo, n'incluez PAS votre repo. .git exécutez ceci à la place :

du -h --max-depth=1 --exclude=.git .

Exemple de sortie de la première commande ci-dessus :

$ du -h --max-depth=1 .git
158G    .git/lfs
6.2M    .git/refs
4.0K    .git/branches
2.5M    .git/info
3.7G    .git/objects
6.2M    .git/logs
68K .git/hooks
162G    .git

Comme vous pouvez le voir, mon total .git La taille du dossier est 162 GB mais 158 GB de cela est mon .git/lfs puisque j'utilise le logiciel tiers " Stockage de gros fichiers Git" ( git lfs ) outil permettant de stocker de gros fichiers binaires. Donc, exécutez ceci pour réduire cela de manière significative . Remarque : le time de toutes les commandes ci-dessous est facultative :

time git lfs prune

(Si git lfs prune échoue avec "panic : runtime error : invalid memory address or nil pointer dereference", voir mes notes ci-dessous).

Source : Comment réduire un repo git LFS ?
Documentation officielle : git-lfs-prune(1) -- Supprimer les anciens fichiers LFS du stockage local

Cela a pris 60 secondes pour courir !

Maintenant, je viens de libérer 62 GB ! Mon .git/lfs est maintenant seulement 96 GB comme indiqué ici :

$ du -h --max-depth=1 .git
96G .git/lfs
6.2M    .git/refs
4.0K    .git/branches
2.5M    .git/info
3.0G    .git/objects
6.2M    .git/logs
68K .git/hooks
99G .git

Ensuite, exécutez ceci pour réduire le .git/objects de quelques centaines de Mo à ~1 Go environ :

time git gc
time git prune

git gc prend environ 3 minutes pour s'exécuter, et git prune prend environ 1 minute.

Vérifiez à nouveau l'utilisation de votre disque avec du -h --max-depth=1 .git . Si vous voulez économiser encore plus d'espace, exécutez ceci :

time git repack -a -d --depth=250 --window=250

Cela prend environ 2 minutes et permet d'économiser quelques centaines de Mo supplémentaires.

Maintenant, vous pouvez vous arrêter ici, OU vous pouvez exécuter cette dernière commande :

time git gc --aggressive --prune

Cette dernière commande permettra d'économiser quelques centaines de Mo supplémentaires mais prendra environ 1,25 heure.

Si git lfs prune échoue avec "panic : runtime error : invalid memory address or nil pointer dereference".

Si git lfs prune échoue avec :

panique : erreur d'exécution : adresse mémoire invalide ou déréférencement de pointeur nul

alors vous avez peut-être une ancienne version de git-lfs installé et que vous devez le mettre à jour. Voici comment procéder :

Tout d'abord, vérifiez la version que vous avez installée. Exécutez man git-lfs et faites défiler jusqu'en bas pour voir la date. Il est peut-être indiqué qu'elle date de 2017, par exemple. Maintenant, mettez à jour votre version avec ces commandes. La première commande vient d'ici : https://packagecloud.io/github/git-lfs/install .

curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
sudo apt update
sudo apt install git-lfs

Exécuter man git-lfs à nouveau et faites défiler jusqu'en bas. Je vois maintenant que ma date est "mars 2021", alors qu'auparavant il s'agissait d'une date quelconque en 2017.

Aussi, si je lance sudo apt install git-lfs encore une fois, ça me dit :

git-lfs est déjà la version la plus récente (2.13.3).

Donc, la mise à jour pour git-lfs a fonctionné, et maintenant l'erreur a disparu et git lfs prune fonctionne à nouveau !

J'ai d'abord documenté ceci dans un commentaire sur GitHub ici : https://github.com/git-lfs/git-lfs/issues/3395#issuecomment-889393444 .

Références :

  1. @knittl : Comment réduire le dossier .git
  2. @David Dehghan : Comment réduire le dossier .git
  3. git lfs prune : Comment réduire un repo git LFS ?
  4. Linus Torvalds sur git repack -a -d --depth=250 --window=250 : https://gcc.gnu.org/legacy-ml/gcc/2007-12/msg00165.html
  5. https://github.com/git-lfs/git-lfs/blob/main/docs/man/git-lfs-prune.1.ronn

Voir aussi :

  1. [mon Q&A] Comment reprendre le hook `git lfs post-checkout` après l'échec du `git checkout` ?

Keywords : git clean dir ; clean .git dir ; clean .git folder ; compresser .git folder ; free hard drive space git ; compress .git directory ; shrink .git dir ; reduce .git dir

0 votes

Des problèmes peuvent-ils survenir si vous supprimez le dossier .git/lfs sans récupérer les données par la suite ?

1 votes

@Showdown, cela dépend de ce que vous avez (ou le propriétaire du repo a) stocké par git lfs . Peut-être contient-il des binaires précompilés dont vous n'avez pas besoin, ou des photos pour montrer comment construire quelque chose (si le dépôt git est un ensemble d'instructions ou un modèle mécanique ou KiCad), ou peut-être a-t-il des documents PDF, etc. Vous seul pouvez le savoir en vous basant sur votre repo particulier. Cela ne fera pas de mal de supprimer .git/lfs . Vous pouvez toujours aller le chercher ou le tirer en cas de besoin. S'il contient le contenu nécessaire à la construction de votre programme, il peut affecter la construction. Exécuter git lfs ls-files pour voir ce qu'il suit.

0 votes

Je vous remercie pour votre réponse. Peut-être que j'ai mal compris le fonctionnement de git, mais l'état actuel ne devrait-il pas à l'extérieur de le dossier .git doit-il être un état complet avec tous les fichiers nécessaires ? Ainsi, seules les méta-données, l'historique des livraisons, les fichiers temporaires, etc. se trouvent à l'intérieur, c'est-à-dire rien qui n'affecte mon travail avec l'état actuel jusqu'à ce que je veuille réinitialiser/réinitialiser/expulser ?

11voto

Let_Me_Be Points 16797

5GB contre 200MB, c'est un peu bizarre. Essayez d'exécuter git gc .

Mais non, à moins que vous ne divisiez votre dépôt en modules, vous ne pouvez pas diminuer la taille de la section .git répertoire.

Chaque clone d'un dépôt git est un dépôt à part entière qui peut agir comme un serveur. C'est le principe de base du contrôle de version distribué.

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