Comment git stocke les fichiers?

J’ai juste commencé à apprendre git et à le faire j’ai commencé à lire le Git Community Book , et dans ce livre, ils disent que SVN et CVS stockent la différence entre les fichiers et que git stocke un instantané de tous les fichiers.

Mais je n’ai pas vraiment compris ce qu’ils entendent par instantané. Est-ce que git fait vraiment une copie de tous les fichiers dans chaque commit parce que c’est ce que j’ai compris de leur explication.

PS: Si quelqu’un a une meilleure source pour apprendre, je l’apprécierais.

Git inclut pour chaque validation une copie complète de tous les fichiers, sauf que, pour le contenu déjà présent dans le repository Git, l’instantané pointera simplement sur ce contenu plutôt que de le dupliquer.
Cela signifie également que plusieurs fichiers avec le même contenu ne sont stockés qu’une seule fois.

Ainsi, un instantané est fondamentalement un commit, faisant référence au contenu d’une structure de répertoire.

Quelques bonnes références sont:

  • gitref.org

Vous dites à Git que vous souhaitez enregistrer un instantané de votre projet avec la commande git commit et qu’il enregistre essentiellement un manifeste de ce à quoi ressemblent tous les fichiers de votre projet à ce stade.

  • immersion git

Lab 12 illustre comment obtenir les instantanés précédents

  • ” Vous auriez pu inventer git (et peut-être vous l’avez déjà fait!) ”

  • Qu’est ce qu’un git “Snapshot”?

  • Apprendre GitHub


Le progit book contient la description plus complète d’un instantané:

La différence majeure entre Git et les autres VCS (Subversion et amis inclus) est la manière dont Git pense à ses données.
Conceptuellement, la plupart des autres systèmes stockent des informations sous la forme d’une liste de modifications basées sur des fichiers. Ces systèmes (CVS, Subversion, Perforce, Bazaar, etc.) considèrent les informations qu’ils conservent comme un ensemble de fichiers et les modifications apscopes à chaque fichier au fil du temps.

VCS basé sur delta

Git ne pense pas ou ne stocke pas ses données de cette façon. Au lieu de cela, Git considère ses données plus comme un ensemble d’instantanés d’un mini système de fichiers.
Chaque fois que vous validez ou enregistrez l’état de votre projet dans Git, il prend essentiellement une photo de tous vos fichiers à ce moment et stocke une référence à cet instantané.
Pour être efficace, si les fichiers n’ont pas changé, Git ne stocke plus le fichier – juste un lien vers le fichier identique précédent déjà stocké.
Git pense à ses données plus comme ci-dessous:

VCS basé sur des instantanés

C’est une distinction importante entre Git et presque tous les autres VCS. Cela fait que Git reconsidère presque tous les aspects du contrôle de version que la plupart des autres systèmes copiaient de la génération précédente. Cela rend Git plus comme un mini système de fichiers avec des outils incroyablement puissants, au lieu de simplement un VCS.


Jan Hudec ajoute ce commentaire important :

Bien que ce soit vrai et important au niveau conceptuel, ce n’est PAS vrai au niveau du stockage.
Git utilise des deltas pour le stockage .
Non seulement cela, mais il est plus efficace que tout autre système. Comme il ne conserve pas l’historique par fichier, quand il souhaite effectuer une compression delta , il prend chaque blob, sélectionne des blobs susceptibles d’être similaires (en utilisant des heuristiques comprenant l’approximation la plus proche de la version précédente et d’autres), générer les deltas et choisir le plus petit. De cette façon, il peut (souvent, dépend de l’heuristique) tirer parti d’autres fichiers similaires ou d’anciennes versions plus similaires que les précédentes. Le paramètre “pack window” permet des performances de trading pour la qualité de compression delta. La valeur par défaut (10) donne généralement des résultats git gc --aggressive , mais lorsque l’espace est limité ou pour accélérer les transferts réseau, git gc --aggressive utilise la valeur 250, ce qui le rend très lent, mais fournit une compression supplémentaire pour les données d’historique.

Git stocke logiquement chaque fichier sous son SHA1. Cela signifie que si vous avez deux fichiers avec exactement le même contenu dans un référentiel (ou si vous renommez un fichier), une seule copie est stockée.

Mais cela signifie également que lorsque vous modifiez une petite partie d’un fichier et que vous le validez, une autre copie du fichier est stockée. La façon dont git résout cela consiste à utiliser des fichiers pack. De temps en temps, tous les fichiers «en vrac» (en fait, pas seulement les fichiers, mais aussi les objects contenant des informations de commit et de répertoire) provenant d’un repository sont rassemblés et compressés dans un fichier de pack. Le fichier de pack est compressé à l’aide de zlib. Et les fichiers similaires sont également compressés en delta.

Le même format est également utilisé pour tirer ou pousser (au moins avec certains protocoles), de sorte que ces fichiers ne doivent plus être recompressés.

Le résultat est qu’un repository git, contenant toute la copie de travail non compressée, les fichiers récents non compressés et les anciens fichiers compressés est généralement relativement petit, plus petit que deux fois la taille de la copie de travail. Et cela signifie qu’il est plus petit que le référentiel SVN avec les mêmes fichiers, même si SVN ne stocke pas l’historique localement.

Les réponses ci-dessus sont plutôt claires, mais j’aimerais append un autre petit concept connu sous le nom d’encodage delta. L’efficacité est enregistrée jusqu’à ce que le fichier de pack soit écrit. Les objects en vrac sont écrits en format compressé mais non delta au moment de chaque validation.