Comment git stocke-t-il les fichiers?


225

Je viens de commencer à apprendre git et pour ce 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 git, je l'apprécierais.


20
Voici un article brillant qui explique en détail le fonctionnement de git. Ce que vous recherchez est probablement le § concernant la base de données d'objets.
greg0ire

Excellent article qui contient des liens vers d'autres excellentes ressources. Je me suis amusé avec ces derniers pendant quelques heures.
mihai

2
J'ai trouvé cet article vraiment sympa décrivant git de l'intérieur: maryrosecook.com/blog/post/git-from-the-inside-out
Sumudu

Réponses:


275

Git inclut pour chaque commit une copie complète de tous les fichiers, sauf que, pour le contenu déjà présent dans le référentiel Git, l'instantané pointera simplement vers ledit 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.

Un instantané est donc essentiellement un commit, se référant au contenu d'une structure de répertoire.

Quelques bonnes références sont:

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

Le laboratoire 12 illustre comment obtenir des instantanés précédents


Le livre de progit a la description la plus complète d'un instantané:

La principale différence entre Git et tout autre VCS (Subversion et amis inclus) est la façon dont Git pense à ses données.
Sur le plan conceptuel, la plupart des autres systèmes stockent les 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 apportées à chaque fichier au fil du temps.

VCS basé sur delta

Git ne pense pas ni ne stocke 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 l'apparence de tous vos fichiers à ce moment-là et stocke une référence à cet instantané.
Pour être efficace, si les fichiers n'ont pas changé, Git ne stocke pas le fichier à nouveau - juste un lien vers le fichier identique précédent qu'il a déjà stocké.
Git pense à ses données plus comme ci-dessous:

VCS basé sur un instantané

Il s'agit d'une distinction importante entre Git et presque tous les autres VCS. Cela oblige Git à reconsidérer presque tous les aspects du contrôle de version que la plupart des autres systèmes ont copiés de la génération précédente. Cela fait de Git plus un mini système de fichiers avec des outils incroyablement puissants construits dessus, plutôt qu'un simple VCS.


Jan Hudec ajoute ce commentaire important :

Bien que cela 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. Parce qu'il ne conserve pas l'historique par fichier, quand il veut faire une compression delta, il prend chaque blob, sélectionne certains blobs qui sont susceptibles d'être similaires (en utilisant une heuristique qui inclut l'approximation la plus proche de la version précédente et d'autres), essaie de générer les deltas et en sélectionne 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 de négocier des performances pour une qualité de compression delta. La valeur par défaut (10) donne généralement des résultats décents, mais lorsque l'espace est limité ou pour accélérer les transferts réseau, git gc --aggressiveutilise la valeur 250, ce qui le rend très lent, mais offre une compression supplémentaire pour les données d'historique.


4
@JanHudec bon point. J'ai inclus votre commentaire dans la réponse pour plus de visibilité.
VonC du

1
Quelqu'un connaît-il le terme informatique pour le modèle de stockage de type Git, alias magasin de valeur basé sur le hachage? (ou quelque chose de similaire)
Joannes Vermorel

34
Dans le contexte de la question même du PO, le premier paragraphe semble vraiment trompeur. Ce n'est pas jusqu'à ce que vous obtenez au dernier paragraphe que nous apprenons que, oh oui, fait Git ne « magasin [...] les différences entre les fichiers. Souhaite vraiment cette information a été signalé en haut et pas enterré si profondément. Cela dit, grâce à en incluant le moins la vraie histoire quelque part dans votre réponse;)
Josh O'Brien

1
@NickVolynkin Great! Je suis heureux que ces réponses trouvent un public plus large.
VonC

1
Un autre bon livre: Git From The Bottom Up: ftp.newartisans.com/pub/git.from.bottom.up.pdf
Jonas Berlin

46

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 utilise des fichiers pack. De temps en temps, tous les fichiers «en vrac» (en fait, pas seulement les fichiers, mais aussi les objets contenant des informations de commit et de répertoire) d'un repo sont rassemblés et compressés dans un fichier pack. Le fichier pack est compressé à l'aide de zlib. Et des fichiers similaires sont également compressés en delta.

Le même format est également utilisé lors de l'extraction ou de la poussée (au moins avec certains protocoles), de sorte que ces fichiers n'ont pas à être recompressés à nouveau.

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


1
ah si mercurial est plus efficace dans l'espace
Ben
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.