git est très très lent lors du suivi de gros fichiers binaires

83

Mon projet a six mois et git est très très lent. Nous suivons environ 30 fichiers d'une taille de 5 Mo à 50 Mo. Ce sont des fichiers binaires et nous les conservons dans git. Je pense que ces fichiers ralentissent git.

Existe-t-il un moyen de supprimer tous les fichiers de taille> 5 Mo du référentiel. Je sais que je perdrais tous ces fichiers et cela me convient.

Idéalement, je voudrais une commande qui listerait tous les gros fichiers (> 5 Mo). Je peux voir la liste, puis je dis d'accord, supprimez ces fichiers et accélérez git.

Je dois mentionner que git est lent non seulement sur ma machine, mais que le déploiement de l'application sur l'environnement de préparation prend maintenant environ 3 heures.

Donc, le correctif devrait être quelque chose qui affectera le serveur et pas seulement les utilisateurs du référentiel.

Nick Vanderbilt
la source
4
Vous pouvez essayer d'utiliser git du git-bigfilesprojet
Jakub Narębski
1
vous pouvez essayer d'utiliser quelque chose comme git-annex pour gérer les fichiers binaires. git-annex.branchable.com
Jed Schneider
Au cas où cela serait utile à quiconque, laissez-moi ajouter que ma version Cygwin de git était suspendue à des rebases. Quand j'ai utilisé Git-Bash, le même référentiel n'avait aucun problème.
Sridhar Sarnobat
Je me demande si c'est toujours le cas. J'espère qu'ils désactivent la compression pour tout ce où l'effet de compression est inférieur à 50% (ou tout autre X% sélectionnable). À un moment donné, la vitesse dépasse clairement l'espace matériel!
Trilarion

Réponses:

125

Faites-vous le ramassage des ordures?

git gc

Cela fait une différence significative en termes de vitesse, même pour les petits dépôts.

kubi
la source
8
Cela se fait automatiquement lorsqu'il y a trop d'encombrement. Je doute que cela aidera vraiment l'OP.
Cascabel
@Jefromi, est-ce nouveau? Je viens de passer à la version 1.7.1 hier, mais avant cela, la version que j'utilisais ne fonctionnait certainement pas automatiquement gc.
kubi
@kubi: Eh bien, cela n'a pas été depuis toujours, mais ce n'est pas tout à fait nouveau - il a été invoqué depuis commit, merge, am et rebase depuis caf9de2 (14 septembre 2007), ou dans la version stable v1.5.4 (1er février 2008 ).
Cascabel
1
Après réflexion, git gcne peut pas être appelé commitet merge, sinon git fsck --unreachable, ne retournerait jamais rien.
kubi
4
Je l'ai trouvé. Le nombre par défaut d'objets en vrac avant l' gcexécution automatique est de 6700, ce qui explique pourquoi je ne l'ai jamais vu fonctionner.
kubi
79

Explication

Git est vraiment bon pour les énormes historiques de petits fichiers texte car il peut les stocker et leurs modifications efficacement. En même temps, git est très mauvais pour les fichiers binaires, et stockera naïvement des copies séparées du fichier ( par défaut, au moins ). Le référentiel devient énorme, puis il devient lent, comme vous l'avez observé.

C'est un problème courant parmi les DVCS, exacerbé par le fait que vous téléchargez chaque version de chaque fichier («tout le référentiel») à chaque fois que vous clonez. Les gars de Kiln travaillent sur un plugin pour traiter ces gros fichiers plus comme Subversion, qui télécharge uniquement les versions historiques à la demande.

Solution

Cette commande listera tous les fichiers dans le répertoire actuel de taille> = 5 Mo.

find . -size +5000000c 2>/dev/null -exec ls -l {} \;

Si vous souhaitez supprimer les fichiers de l'historique complet du référentiel, vous pouvez utiliser cette idée avec git filter-branchpour parcourir l'historique et vous débarrasser de toutes les traces de fichiers volumineux. Après cela, tous les nouveaux clones du référentiel seront plus légers. Si vous souhaitez développer un référentiel sans clonage, vous trouverez des instructions sur la page de manuel (voir «Liste de contrôle pour réduire un référentiel»).

git filter-branch --index-filter \
    'find . -size +5000000c 2>/dev/null -exec git rm --cached --ignore-unmatch {} \;'

Un mot d'avertissement : cela rendra votre référentiel incompatible avec d'autres clones, car les arbres et les index ont des fichiers différents enregistrés; vous ne pourrez plus les pousser ou les tirer.

Andres Jaan Tack
la source
4
Remarque: il s'agit de la version Unix / Linux de find, pas de Windows find.exe.
Craig Trader
1
+1. Pourrait vouloir envoyer la sortie de findvers un fichier d'abord, vérifier la liste, puis utiliser git rm, juste au cas où il y aurait de faux résultats. Vous pouvez également vérifier git statusaprès avoir supprimé les fichiers volumineux et utiliser git checkout HEAD <file>pour récupérer tous les fichiers supprimés par erreur.
Cascabel
2
Je pense que votre commentaire selon lequel git "stocke des copies séparées par défaut" est à l'envers. Selon la chaîne de messagerie que vous avez liée ( thread.gmane.org/gmane.comp.version-control.git/146957/… ) par défaut, git essaie de comparer les fichiers binaires - et c'est ce qui cause le problème; pas le stockage.
Alexander Bird
16

Voici une révision censurée destinée à être moins négative et incendiaire:

Git a une faiblesse bien connue en ce qui concerne les fichiers qui ne sont pas des fichiers texte ligne par ligne. Il n'y a actuellement aucune solution et aucun plan annoncé par l'équipe git principale pour résoudre ce problème. Il existe des solutions de contournement si votre projet est petit, disons 100 Mo ou plus. Il existe des branches du projet git pour résoudre ce problème d'évolutivité, mais ces branches ne sont pas matures pour le moment. Certains autres systèmes de contrôle de révision n'ont pas ce problème spécifique. Vous devez considérer ce problème comme l'un des nombreux facteurs lorsque vous décidez de sélectionner git comme système de contrôle des révisions.

John
la source
8
"Git a une faiblesse bien connue ..." - citation nécessaire
Nav
6
Je sais cela. qui a besoin de citations lorsque sa connaissance commune réelle. n'utilisez pas git pour le binaire. utiliser la gestion forcée ou spécialisée des actifs.
v.oddou
1
@ v.oddou Eh bien, il y a une différence entre "je le sais" et "sa connaissance commune actuelle". Ce truc, c'est que tout le monde ne le sait pas et ce n'est probablement même pas complètement vrai. Donc, tout type de citation améliore cette réponse. C'est correct mais sûrement pas exceptionnel et sauvegardé.
Trilarion
2
Eh bien, pas pour alimenter le feu, mais si vous effectuez une recherche Google pour "git et les fichiers binaires lents", il y a beaucoup de liens qui sont trouvés qui signalent que les utilisateurs ont des problèmes pour gérer les fichiers binaires dans git. De plus, les développeurs qui utilisent un SCM ou un autre connaissent les forces et les faiblesses de chaque système ... donc, git a développé la réputation de devenir très lent lorsque des fichiers binaires sont jetés dans un dépôt.
AhiyaHiya
c'est dans toutes les ressources d'introduction que j'ai utilisées que git est mauvais avec les fichiers binaires. git-annex existe pour résoudre ce problème. git est génial, mais pas pour les données binaires. Il serait bon de créer un lien vers des fourches en ajoutant des fonctionnalités binaires, afin que les gens puissent soutenir le travail.
fuzzyTew le
15

Il n'y a rien de spécifique sur les fichiers binaires et la façon dont git les gère. Lorsque vous ajoutez un fichier à un référentiel git, un en-tête est ajouté et le fichier est compressé avec zlib et renommé après le hachage SHA1. C'est exactement la même chose quel que soit le type de fichier. Il n'y a rien dans la compression zlib qui le rend problématique pour les fichiers binaires.

Mais à certains moments (pousser, gc) Git commence à examiner la possibilité de compresser le contenu en delta. Si git trouve des fichiers similaires (nom de fichier, etc.), il les met dans la RAM et commence à les compresser ensemble. Si vous avez 100 fichiers et que chacun d'eux arrive à 50 Mo, il essaiera de mettre 5 Go dans la mémoire en même temps. À cela, vous devez en ajouter pour que les choses fonctionnent. Votre ordinateur n'a peut-être pas cette quantité de RAM et il commence à basculer. Le processus prend du temps.

Vous pouvez limiter la profondeur de la compression delta afin que le processus n'utilise pas autant de mémoire, mais le résultat est une compression moins efficace. (core.bigFileThreshold, attribut delta, pack.window, pack.depth, pack.windowMemory etc)

Il y a donc beaucoup de choses que vous pouvez faire pour que git fonctionne très bien avec des fichiers volumineux.

Martin
la source
4
Voir ici pour une explication sur la façon de désactiver ces tentatives "delta".
Alexander Bird
6

Une façon d'accélérer les choses est d'utiliser le --depth 1drapeau. Consultez la page de manuel pour plus de détails. Je ne suis pas un grand gourou, mais je crois que cela dit de faire l'équivalent de a p4 getou an svn get, c'est-à-dire que cela ne vous donne que les derniers fichiers uniquement au lieu de "donnez-moi toutes les révisions de tous les fichiers à travers tout le temps" qui est que git clonefait.

David
la source
1
Cela ne vous permet pas de pousser depuis le référentiel, c'est donc d'une utilité limitée.
Martin
4

avez-vous dit à git que ces fichiers sont binaires?

par exemple ajouté *.ext binaryà votre référentiel.gitattributes

sml
la source
Je suppose que dire à git que les fichiers sont des binaires accélère les choses.
Nick Vanderbilt
cela peut arriver si l'heuristique de git ne peut pas dire qu'un fichier est automatiquement binaire.
sml
2

J'utilise Git depuis 2008 à la fois sous Windows et GNU / linux et la plupart des fichiers que je trace sont des fichiers binaires. Certains de mes dépôts font plusieurs Go et contiennent du Jpeg et d'autres médias. J'ai de nombreux ordinateurs à la maison et au travail exécutant Git.

Je n'ai jamais eu les symptômes décrits dans le message original. Mais il y a à peine quelques semaines, j'ai installé MsysGit sur un ancien ordinateur portable Win-XP et presque tout ce que j'ai fait, cela a mis git à l'arrêt. Même le test avec seulement deux ou trois petits fichiers texte était ridiculement lent. Nous parlons d'environ 10 minutes pour ajouter un fichier de moins de 1k ... il semble que les processus git soient restés vivants pour toujours. Tout le reste a fonctionné comme prévu sur cet ordinateur.
J'ai rétrogradé de la dernière version à 1.6 quelque chose et les problèmes ont disparu ...
J'ai d'autres ordinateurs portables de la même marque, également avec Win-XP installé par le même service informatique, forment la même image, où Git fonctionne bien quelle que soit la version. .. Il doit donc y avoir quelque chose de bizarre avec cet ordinateur en particulier.

J'ai également fait quelques tests avec des fichiers binaires et de la compression. Si vous avez une image BMP et que vous y apportez de petites modifications et que vous les validez, git gc se compressera très bien. Donc ma conclusion est que la compression ne dépend pas du fait que les fichiers sont binaires ou non.

Martin
la source
-2

Configurez simplement les fichiers pour qu'ils soient ignorés. Voir le lien ci-dessous:

http://help.github.com/git-ignore/

Joshlrogers
la source
@Jefromi en fait si vous regardez le lien que j'ai posté, vous verrez qu'il y a des instructions dans le deuxième paragraphe lui disant exactement quoi faire dans ce cas.
joshlrogers
14
Vrai. Mais le contenu direct de votre réponse est "ignorer les fichiers", et non "supprimer les fichiers du suivi puis les ignorer". Il est généralement préférable de l'écrire ici plutôt que de créer un lien vers un autre site.
Cascabel
-24

C'est parce que git n'est pas évolutif.

C'est une limitation sérieuse dans git qui est noyée par le plaidoyer git. Recherchez dans les listes de diffusion de git et vous trouverez des centaines d'utilisateurs qui se demandent pourquoi juste un maigre 100 Mo d'images (par exemple, pour un site Web ou une application) met git à genoux. Le problème semble être que presque tout git repose sur une optimisation qu'ils appellent «emballage». Malheureusement, l'emballage est inefficace pour tous les fichiers texte sauf les plus petits (c'est-à-dire le code source). Pire, il devient de moins en moins efficace au fur et à mesure que l'histoire augmente.

C'est vraiment une faille embarrassante dans git, qui est présentée comme "rapide" (malgré le manque de preuves), et les développeurs de git en sont bien conscients. Pourquoi ne l'ont-ils pas corrigé? Vous trouverez des réponses sur la liste de diffusion git de développeurs git qui ne reconnaîtront pas le problème car les documents Photoshop (* .psd) sont au format propriétaire. Oui, c'est vraiment si mauvais.

Voici le résultat:

Utilisez git pour de petits projets de code source uniquement pour lesquels vous n'avez pas envie de configurer un dépôt séparé. Ou pour les petits projets de code source uniquement dans lesquels vous souhaitez tirer parti du modèle de copie de l'ensemble du dépôt de git de développement décentralisé. Ou lorsque vous souhaitez simplement apprendre un nouvel outil. Ce sont toutes de bonnes raisons d'utiliser git, et c'est toujours amusant d'apprendre de nouveaux outils.

N'utilisez pas git si vous avez une grande base de code, des binaires, un historique énorme, etc. Un seul de nos dépôts est un TB. Git ne peut pas le gérer. VSS, CVS et SVN le gèrent très bien. (SVN gonfle, cependant.)

Aussi, donnez à git le temps de mûrir. Il est encore immature, mais il a beaucoup d'élan. Avec le temps, je pense que la nature pratique de Linus dépassera les puristes de l'OSS, et git sera éventuellement utilisable dans un domaine plus large.

John
la source
15
Cette réponse est vraiment trop négative et incendiaire. Oui, git a des problèmes d'évolutivité avec les fichiers binaires . C'est assez évolutif et rapide pour le code. Il existe de nombreuses preuves de la vitesse (malgré votre affirmation du contraire), même en ignorant le fait que CVS / SVN nécessite un accès réseau au lieu d'un accès disque pour de nombreuses opérations. Il existe de nombreux grands projets avec d'énormes histoires utilisant git.
Cascabel
8
Et ... votre insistance sur Photoshop? Je ne vais pas perdre mon temps à écrire une réponse détaillée, mais si à la lecture de l'intégralité du fil thread.gmane.org/gmane.comp.version-control.git/146957/ ... (peut-être que vous êtes ennuyé parce que le John en the thread is you?), je vois beaucoup de réponses raisonnables sur la meilleure façon de gérer cela avec git actuel, comment cela pourrait être traité dans le futur, et pourquoi ce n'est pas leur première priorité.
Cascabel
14
Ouais, je ne pense pas que tu as raison, ici. Git fonctionne bien trop bien pour que le noyau Linux mérite un rejet, "n'est pas évolutif".
Andres Jaan Tack
1
Ce commentaire serait plus crédible s'il avait des liens ou des données pour le sauvegarder. BTW, que pensez-vous de mercurial?
vy32
3
Peut-être qu'il n'exprime pas une opinion populaire, mais je pense que le vote à la baisse était plus excessif dans sa «négativité» que la réponse du PO. Nous devrions encourager la dissidence, pas empiler simplement parce que quelqu'un n'aime pas la saveur de contrôle de version de l'année. GIT n'est vraiment pas bien adapté au suivi des fichiers binaires. Mais cela fonctionne très bien pour le code source, c'est l'intention principale, c'est pourquoi il fonctionne très bien au noyau Linux.
dyasta