Comment les ID de validation Git sont-ils générés pour identifier de manière unique les validations?
Exemple: 521747298a3790fde1710f3aa2d03b55020575aa
Comment ça marche? Sont-ils uniques pour chaque projet? Ou pour les référentiels Git dans le monde?
Un ID de validation Git est un hash SHA-1 de chaque chose importante concernant la validation. Je ne vais pas tous les énumérer, mais voici les plus importants ...
Modifiez tout cela et l'ID de validation change. Et oui, le même commit avec les mêmes propriétés aura le même ID sur une machine différente. Cela sert à trois fins. Tout d'abord, cela signifie que le système peut savoir si une validation a été falsifiée. Il est cuit directement dans l'architecture.
Deuxièmement, on peut comparer rapidement les validations simplement en regardant leurs identifiants. Cela rend les protocoles réseau de Git très efficaces. Vous voulez comparer deux commits pour voir s'ils sont identiques? Pas besoin d'envoyer le diff entier, envoyez simplement les identifiants.
Troisièmement, et c'est le génie, deux commits avec les mêmes identifiants ont la même histoire . C'est pourquoi l'ID des validations précédentes fait partie du hachage. Si le contenu d'une validation est le même mais que les parents sont différents, l'ID de validation doit être différent. Cela signifie que lorsque vous comparez des référentiels (comme dans un push ou un pull) une fois que Git trouve un commit en commun entre les deux référentiels, il peut arrêter de vérifier. Cela rend la poussée et la traction extrêmement efficaces. Par exemple...
Origin
A - B - C - D - E [master]
A - B [Origin/master]
La conversation réseau pour git fetch Origin
va quelque chose comme ça ...
local
Hey Origin, quelles branches avez-vous?Origin
J'ai un master chez E.local
Je n'ai pas E, j'ai ton maître à B.Origin
B vous dites? J'ai B et c'est un ancêtre de E. Cela vérifie. Permettez-moi de vous envoyer C, D et E.C'est également la raison pour laquelle lorsque vous réécrivez un commit avec rebase, tout ce qui doit changer après. Voici un exemple.
A - B - C - D - E - F - G [master]
Disons que vous réécrivez D, juste pour changer un peu le message du journal. Maintenant D ne peut plus être D, il doit être copié dans un nouveau commit que nous appellerons D1.
A - B - C - D - E - F - G [master]
\
D1
Alors que D1 peut avoir C comme parent (C n'est pas affecté, les commits ne connaissent pas leurs enfants), il est déconnecté de E, F et G. Si nous changeons le parent de E en D1, E ne peut plus être E. Il doit être copié dans un nouveau commit E1.
A - B - C - D - E - F - G [master]
\
D1 - E1
Et ainsi de suite avec F à F1 et G à G1.
A - B - C - D - E - F - G
\
D1 - E1 - F1 - G1 [master]
Ils ont tous le même code, juste des parents différents (ou dans le cas de D1, un message de validation différent).
Vous pouvez voir exactement ce qui se passe dans la création d'un ID de validation en exécutant
git cat-file commit HEAD
Cela vous donnera quelque chose comme
tree 07e239f2f3d8adc12566eaf66e0ad670f36202b5
parent 543a4849f7201da7bed297b279b7b1e9a086a255
author Justin Howard <[email protected]> 1426631449 -0700
committer Justin Howard <[email protected]> 1426631471 -0700
My commit message
Ça te donne:
Git prend tout cela et en fait un hachage sha1. Vous pouvez reproduire l'ID de validation en exécutant
(printf "commit %s\0" $(git cat-file commit HEAD | wc -c); git cat-file commit HEAD) | sha1sum
Cela commence par l'impression de la chaîne commit
suivie d'un espace et du nombre d'octets de cat-file
blob de texte. Il ajoute ensuite le cat-file
blob à celui suivi d'un octet nul. Tout cela passe ensuite par sha1sum
.
Comme vous pouvez le voir, il n'y a rien qui identifie le projet ou le référentiel dans ces informations. La raison pour laquelle cela ne pose pas de problème est qu'il est astronomiquement improbable que deux hachages de validation différents entrent en collision.