Pourquoi les référentiels Git / Mercurial utilisent-ils moins d'espace?

15

J'ai lu plusieurs discussions ici et sur SO que les référentiels DVCS utilisent à peu près le même espace ou moins que leurs homologues centralisés. Je l'ai peut-être manqué, mais je n'ai pas trouvé une bonne explication de la raison. Quelqu'un sait?

Alex Florescu
la source
1
Non, merci! Je comprends donc de ceux-ci qu'il y a deux réponses: la compression en utilisant zlib et l'enregistrement des objets en tant que packfiles lorsque cela est possible. Les exemples de Mozilla sont également super!
Alex Florescu
1
@Alex Non, cela manque la raison principale. SVN enregistre des instantanés complets, Git et Mercurial n'enregistrent que la révision HEAD et les différences. L'utilisation de la compression conventionnelle peut vous donner des taux optimaux d'environ 60 à 80% de compression. L'utilisation de diffs pourrait vous donner jusqu'à 99%. Ces chiffres sont cependant tirés de mon cul - les vrais chiffres peuvent différer; la tendance sera cependant la même.
Konrad Rudolph
@KonradRudolph, n'est-ce pas de cela qu'il s'agit?
Alex Florescu
@Alex Pas vraiment. Autant que je sache, le packfile est également en train de regrouper plusieurs fichiers en un seul. Ce n'est pas nécessairement lié.
Konrad Rudolph

Réponses:

18

D'après ma propre expérience, les affirmations suivantes sont toutes vraies:

  • Git est très efficace pour stocker des fichiers texte et ne stocke que les fichiers modifiés. ainsi, lorsque vous comparez SVN et Git pour comparer les tailles de référentiel, elles peuvent être similaires, ou il peut même y avoir un petit avantage pour Git.
  • C'est complètement faux si vous comparez la taille des référentiels où une quantité importante de fichiers sont des fichiers bureautiques (comme MS Word, Excel, PowerPoint, ...). Ici, Git stocke également des copies complètes, ce qui signifie que 10 petits changements sur une pile de diapositives PowerPoint entraînent 10 copies complètes, où Subversion ne stocke qu'un diff binaire, qui peut être un facteur 100 plus petit.

Si vous comparez l'emplacement de paiement (qui est un référentiel en soi avec Git), l'histoire est totalement différente:

  • Subversion stocke pour chaque fichier une copie complète, donc la taille de votre emplacement de paiement est normalement 2 fois la taille des fichiers eux-mêmes.
  • Git stocke localement l'historique complet du référentiel, donc en fonction de la taille de l'historique, celui-ci peut être plus petit ou beaucoup plus grand que celui de la copie d'extraction Subversion.

Si vous comparez la quantité d'octets que vous devez télécharger ou télécharger, c'est à nouveau différent.

  • Subversion doit normalement envoyer ou recevoir moins d'octets, car il n'envoie que des différences. Il doit le faire à chaque validation et mise à jour.
  • Git doit obtenir l'intégralité du référentiel (initialement), puis envoie des fichiers complets (compressés?) Qui ne sont pas si différents pour les fichiers texte, mais peuvent être différents pour les fichiers binaires. Et oui, Git ne le fait que lorsque vous poussez ou tirez quelque chose vers le référentiel distant.

Donc, à la fin, vous comparez des pommes avec des oranges, et selon ce que vous voulez faire avec Subversion ou Git, le résultat peut être différent.


@jk a demandé des copies complètes ou des différences binaires, et je n'ai pas pu répondre à cette question. J'ai demandé à Matthew McCullough qui a donné un atelier Git récemment à Jax 2012 (que j'ai visité). Il a pris le temps (merci beaucoup à lui) d'expliquer de manière détaillée le fonctionnement interne de Git. Donc oui, il y a une compression qui fonctionne (et je ferai également une expérience avec un fichier Microsoft Office et je comparerai cela avec son essentiel), mais non, la compression est effectuée sur l'ensemble du fichier. Citant de son essence:

Les objets en vrac sont écrits au format compressé, mais non delta au moment de chaque validation.

mliebelt
la source
1
êtes-vous sûr que git stocke des copies complètes des fichiers de bureau? Je pense qu'il stocke également des différences binaires. bien sûr, le véritable problème avec ce type de fichiers est qu'ils sont souvent déjà compressés, donc une petite modification peut entraîner la modification de l'ensemble du fichier
jk.
2
Demandé à quelqu'un (par email) qui en sait beaucoup plus que moi, et qui inclura alors sa réponse dans ma réponse.
mliebelt
6
Git traite les fichiers texte et binaires exactement de la même manière à tous égards en ce qui concerne le stockage. Les objets lâches et compactés ne sont pas liés au texte ou aux binaires. La raison pour laquelle les fichiers binaires entraînent souvent des différences beaucoup plus importantes que les fichiers texte est que de nombreux formats binaires (y compris tous les nouveaux formats Office) sont déjà compressés et donc même un petit changement de contenu provoque souvent de gros changements dans le blob binaire résultant. Cela concerne également git et subversion, mais subversion ne prend que la pénalité sur le serveur, tandis que git est partout.
Jan Hudec
4
Les objets lâches vs emballés n'ont rien à voir avec le texte vs binaire. C'est l'amortissement du travail difficile de trouver les diff binaires. La vitesse est une caractéristique importante de git, donc pendant son fonctionnement normal, git zippe uniquement les nouvelles données et les claque dans le référentiel. Ce sont des objets en vrac. Que lorsque vous le lui demandez en appelant git gcou que trop d'objets lâches s'accumulent, il trouve de bons candidats pour les compresser en delta (git peut être différent de ceux de la version précédente), stocke les deltas dans un "pack" et supprime les objets lâches.
Jan Hudec
3
Pour ceux qui sont intéressés par les chiffres du monde réel: je viens de comparer deux copies de travail du même repo. La copie de travail SVN est d'environ 2,9 Go, la copie de travail GIT est d'environ 0,8 Go.
JensG