Commentaire de Bryan Pendleton contient la bonne réponse : votre git push
a constitué un "paquet mince". Toutes les opérations "fetch" et "push" sur des protocoles intelligents utilisent des "thin packs" en permanence, afin de minimiser le trafic sur le réseau.
Tout fichier pack utilise compression delta . Les fichiers de paquets Git normaux ne delta-compressent les objets que par rapport à d'autres objets du même paquet (ces autres objets peuvent également être delta-compressés, mais seulement par rapport à d'autres objets du même paquet). Un "thin pack" est un fichier pack qui viole délibérément cette règle : il delta-compresse des objets par rapport à d'autres objets (libres ou emballés) stockés ailleurs. Lorsqu'il reçoit un "thin pack", un Git doit "réparer" le "thin pack" en l'"engraissant" avec les objets manquants, ou simplement le détruire (en explosant le "thin pack" en objets individuels, non delta-compressés).
Supposons que votre Git et un autre Git négocient l'envoi d'un gigaoctet de données (dans un nombre quelconque de fichiers - disons 1 pour simplifier), mais que les deux Git découvrent que vous avez tous deux déjà un gigaoctet de données de fichiers, et que la fonction nouveau peuvent être représentées comme suit : "copier les anciennes données, supprimer la lettre a
à partir du milieu, et insérer the
à la place", ou quelque chose de tout aussi court et simple. Quel que soit le Git qui effectue l'envoi, il produit un objet compressé en delta disant "starting from object with hash h , supprimer 1 octet à l'offset x ajouter 3 octets the
à l'offset x ". Cet objet compressé en delta prend beaucoup de temps à l'unité centrale - peut-être même une seconde entière - pour être calculé, mais seulement quelques dizaines d'octets d'espace. Le fichier pack résultant est minuscule et traverse le réseau en quelques microsecondes. Le Git récepteur l'enrichit en ajoutant l'objet manquant de 1 Go, et le transfert est terminé.
Dans ce cas particulier, completed with 12 local objects
signifie que le paquet mince s'est appuyé sur 12 objets que votre Git a dit à leur Git que vous aviez déjà. En raison du DAG de Git, votre Git peut être en mesure de dire à leur Git que vous avez ces objets en envoyant juste un ID de hachage : si vous avez un engagement C Vous avez tous les arbres et tous les blobs qui s'engagent. C a, et - tant que vous n'avez pas un référentiel "superficiel" - vous également ont tous les ancêtres pour s'engager C et tous les arbres et blobs qui accompagnent ces engagements d'ancêtres.
Ce type de compression est donc une conséquence directe de la théorie des graphes. C'est également la raison pour laquelle, même pour les très grands projets, le clone initial peut être lent, mais la plupart des projets de la git fetch
les mises à jour ont tendance à être assez rapides. La principale exception à cette règle est lorsque vous donnez à Git des objets de données qui ne se compriment pas bien par rapport aux objets de données précédents. Cela inclut les fichiers binaires déjà compressés, comme les images JPG ou les tarballs compressés. (Ironiquement, un les tarballs compressés pourraient, en théorie du moins, être beaucoup mieux compressés, bien que le xdelta modifié de Git n'ait pas fait un excellent travail sur eux dans quelques cas que j'ai testés par le passé).