Quelles sont les limites de fichiers dans Git (nombre et taille)?

175

Quelqu'un sait-il quelles sont les limites Git pour le nombre de fichiers et la taille des fichiers?

Alexandre Rademaker
la source
Sous Windows, la taille maximale du fichier est de 4 Go (à partir de juillet 2020), en raison d'un bogue: github.com/git-for-windows/git/issues/1063
cowlinator le

Réponses:

161

Ce message de Linus lui-même peut vous aider avec d'autres limites

[...] CVS, c'est-à-dire qu'il finit par être plutôt orienté vers un modèle "un fichier à la fois".

Ce qui est agréable dans ce que vous pouvez avoir un million de fichiers, et seulement vérifier certains d'entre eux - vous ne serez jamais même voir l'impact des autres fichiers 999,995.

Fondamentalement, Git ne regarde jamais moins que l'ensemble du dépôt. Même si vous limitez un peu les choses (c'est-à-dire vérifier juste une partie, ou faire remonter un peu l'historique), git finit toujours par se soucier de tout et transporter les connaissances.

Donc, git évolue vraiment mal si vous le forcez à tout regarder comme un énorme dépôt. Je ne pense pas que cette partie soit vraiment réparable, même si nous pouvons probablement l'améliorer.

Et oui, alors il y a les problèmes de «gros fichiers». Je ne sais vraiment pas quoi faire des gros fichiers. On les suce, je sais.

Voir plus dans mon autre réponse : la limite avec Git est que chaque référentiel doit représenter un " ensemble cohérent de fichiers ", le "tout système" en lui-même (vous ne pouvez pas taguer "partie d'un référentiel").
Si votre système est composé de parties autonomes (mais interdépendantes), vous devez utiliser des sous-modules .

Comme l'illustre la réponse de Talljoe , la limite peut être une limite système (grand nombre de fichiers), mais si vous comprenez la nature de Git (à propos de la cohérence des données représentée par ses clés SHA-1), vous réaliserez la vraie "limite" est une utilisation : c'est-à-dire que vous ne devriez pas essayer de tout stocker dans un dépôt Git, à moins que vous ne soyez prêt à toujours tout récupérer ou baliser. Pour certains grands projets, cela n'aurait aucun sens.


Pour un examen plus approfondi des limites de git, consultez « git avec de gros fichiers »
(qui mentionne git-lfs : une solution pour stocker des fichiers volumineux en dehors du dépôt git. GitHub, avril 2015)

Les trois problèmes qui limitent un dépôt git:

  • fichiers énormes (le xdelta pour packfile est en mémoire uniquement, ce qui n'est pas bon avec les gros fichiers)
  • un grand nombre de fichiers , ce qui signifie un fichier par objet blob, et ralentir git gc pour générer un fichier pack à la fois.
  • d'énormes fichiers pack , avec un index packfile inefficace pour récupérer les données du (énorme) fichier pack.

Un fil de discussion plus récent (février 2015) illustre les facteurs limitants pour un dépôt Git :

Quelques clones simultanés à partir du serveur central ralentiront-ils également d'autres opérations simultanées pour d'autres utilisateurs?

Il n'y a pas de verrou sur le serveur lors du clonage, donc en théorie le clonage n'affecte pas les autres opérations. Le clonage peut cependant utiliser beaucoup de mémoire (et beaucoup de CPU à moins que vous n'activiez la fonction bitmap d'accessibilité, ce que vous devriez).

Est-ce que ' git pull' sera lent?

Si nous excluons le côté serveur, la taille de votre arbre est le facteur principal , mais vos fichiers de 25k devraient être bien (linux a 48k fichiers).

' git push'?

Celui-ci n'est pas affecté par la profondeur de l'historique de votre repo ou la largeur de votre arbre, donc cela devrait être rapide.

Ah le nombre de refs peut affecter à la fois git-pushet git-pull.
Je pense que Stefan sait mieux que moi dans ce domaine.

' git commit'? (Il est répertorié comme lent dans la référence 3. ) ' git status'? (Ralentissez à nouveau dans la référence 3 même si je ne le vois pas.)
(Aussi git-add)

Encore une fois, la taille de votre arbre. À la taille de votre repo, je ne pense pas que vous ayez à vous en soucier.

Certaines opérations peuvent ne pas sembler être quotidiennes, mais si elles sont fréquemment appelées par le front-end Web vers GitLab / Stash / GitHub, etc., elles peuvent devenir des goulots d'étranglement. (par exemple, « git branch --contains» semble terriblement affecté par un grand nombre de branches.)

git-blame peut être lent lorsqu'un fichier est beaucoup modifié.

VonC
la source
4
@ Thr4wn: voir aussi stackoverflow.com/questions/1979167/git-submodule-update/… pour en savoir plus sur la page du sous-module GitPro. Pour une version plus courte: stackoverflow.com/questions/2065559/…
VonC
1
Lien mis à jour pour la documentation de git submoules = git-scm.com/book/en/Git-Tools-Submodules
JHowIX
Je me demande vraiment, avec autant de sqlite et de nombreuses alternatives de base de données disponibles sur Linux, pourquoi ils ne pourraient pas simplement utiliser une base de données facile à sauvegarder, répliquer et faire évoluer.
Akash Kava
"git évolue vraiment mal si vous le forcez à tout regarder comme un énorme dépôt" qu'est-ce que cela dit sur l'évolutivité des monorepos?
ephemer le
@ephemer Ce qui est dit, c'est que ... cette citation date d'il y a 10 ans. Depuis lors, en 2017, Microsoft a son propre monorepo ( devblogs.microsoft.com/bharry / ... : 300 Go +) et des améliorations sont toujours à venir en 2019: stackoverflow.com/a/57129687/6309
VonC
36

Il n'y a pas de vraie limite - tout est nommé avec un nom de 160 bits. La taille du fichier doit être représentable dans un nombre de 64 bits donc pas de limite réelle non plus.

Il y a cependant une limite pratique. J'ai un référentiel d'environ 8 Go avec> 880 000 fichiers et git gc prend un certain temps. L'arbre de travail est assez volumineux, donc les opérations qui inspectent tout le répertoire de travail prennent un certain temps. Cependant, ce dépôt n'est utilisé que pour le stockage de données, ce n'est donc qu'un ensemble d'outils automatisés qui le gèrent. Extraire les modifications du référentiel est beaucoup, beaucoup plus rapide que de resynchroniser les mêmes données.

%find . -type f | wc -l
791887
%time git add .
git add .  6.48s user 13.53s system 55% cpu 36.121 total
%time git status
# On branch master
nothing to commit (working directory clean)
git status  0.00s user 0.01s system 0% cpu 47.169 total
%du -sh .
29G     .
%cd .git
%du -sh .
7.9G    .
Talljoe
la source
2
Bien qu'il y ait une réponse «plus correcte» ci-dessus parlant des limites théoriques, cette réponse me semble plus utile car elle permet de comparer la propre situation avec la vôtre. Merci.
Bananeweizen
1
Très intéressant. Comment est-il possible que la copie de travail soit plus volumineuse que le .gitrépertoire? Mon hypothèse naïve était que le .gitcontient une copie du répertoire de travail plus l'historique, il doit donc être plus grand. Quelqu'un peut-il m'indiquer une ressource comprenant comment ces tailles sont liées?
bluenote10
1
@ bluenote10 Le contenu du .gitrépertoire est compressé. Ainsi, un référentiel avec relativement peu de validations aura probablement un historique compressé plus petit que le répertoire de travail non compressé. Mon expérience montre qu'en pratique, avec du code C ++, tout l'historique a généralement à peu près la même taille que le répertoire de travail.
prapin
28

Si vous ajoutez des fichiers trop volumineux (Go dans mon cas, Cygwin, XP, 3 Go de RAM), attendez-vous à cela.

fatal: mémoire insuffisante, échec de malloc

Plus de détails ici

Mise à jour 3/2/11: Saw similaire dans Windows 7 x64 avec Tortoise Git. Tonnes de mémoire utilisée, réponse du système très très lente.

Brian Carlton
la source
17

En février 2012, il y avait un fil de discussion très intéressant sur la liste de diffusion Git de Joshua Redstone, un ingénieur logiciel de Facebook testant Git sur un énorme référentiel de test:

Le dépôt de test a 4 millions de commits, un historique linéaire et environ 1,3 million de fichiers.

Les tests qui ont été exécutés montrent que pour un tel dépôt, Git est inutilisable (opération à froid durant quelques minutes), mais cela peut changer dans le futur. Fondamentalement, les performances sont pénalisées par le nombre d' stat()appels au module FS du noyau, donc cela dépendra du nombre de fichiers dans le dépôt et de l'efficacité de la mise en cache FS. Voir également ce résumé pour une discussion plus approfondie.

CharlesB
la source
2
+1 Intéressant. Cela fait écho à mes propres réponses sur les limites de git détaillant les limitations sur les fichiers énormes / nombre de fichiers / packfiles.
VonC
2

Cela dépend de votre signification. Il existe des limites de taille pratiques (si vous avez beaucoup de gros fichiers, cela peut devenir ennuyeux). Si vous avez beaucoup de fichiers, les analyses peuvent également être lentes.

Cependant, il n'y a pas vraiment de limites inhérentes au modèle. Vous pouvez certainement l'utiliser mal et être misérable.

Dustin
la source
1

Je pense qu'il est bon d'essayer d'éviter les gros fichiers commits comme faisant partie du référentiel (par exemple, un vidage de base de données pourrait être mieux ailleurs), mais si l'on considère la taille du noyau dans son référentiel, vous pouvez probablement vous attendre à travailler confortablement avec quelque chose de plus petit et de moins complexe que cela.

Kzqai
la source
1

J'ai une quantité généreuse de données stockées dans mon dépôt en tant que fragments JSON individuels. Il y a environ 75 000 fichiers dans quelques répertoires et cela ne nuit pas vraiment aux performances.

Les vérifier pour la première fois était, de toute évidence, un peu lent.

funwhilelost
la source
1

J'ai trouvé cela en essayant de stocker un nombre massif de fichiers (350k +) dans un repo. Oui, stocker. Des rires.

$ time git add . 
git add . 333.67s user 244.26s system 14% cpu 1:06:48.63 total

Les extraits suivants de la documentation Bitbucket sont assez intéressants.

Lorsque vous travaillez avec un clonage de référentiel DVCS, vous travaillez avec tout le référentiel et toute son histoire. En pratique, une fois que votre référentiel dépasse 500 Mo, vous pouvez commencer à voir des problèmes.

... 94% des clients Bitbucket ont des référentiels inférieurs à 500 Mo. Le noyau Linux et Android font moins de 900 Mo.

La solution recommandée sur cette page consiste à diviser votre projet en petits morceaux.

Kasisnu
la source
Je suppose que c'est assez dépassé. À l'heure actuelle, il ne semble y avoir rien sur le repo Android (ni Linux) sur le site auquel vous créez un lien. Mais je me demande si ce n'était pas inexact même à l'époque? Par exemple, comparez cette réponse . Peut-être qu'ils voulaient dire autre chose?
jjj