Les hachages SHA1 stockés dans les objets de l'arborescence (tels que renvoyés par git ls-tree
) ne correspondent pas aux hachages SHA1 du contenu du fichier (tels que renvoyés par sha1sum
)
$ git cat-file blob 4716ca912495c805b94a88ef6dc3fb4aff46bf3c | sha1sum
de20247992af0f949ae8df4fa9a37e4a03d7063e -
Comment git calcule-t-il les hachages de fichiers? Compresse-t-il le contenu avant de calculer le hachage?
Réponses:
$ echo -e 'blob 14\0Hello, World!' | shasum 8ab686eafeb1f44702738c8b0f24f2567c36da6d
Source: http://alblue.bandlem.com/2011/08/git-tip-of-week-objects.html
la source
echo 'Hello, World!' | git hash-object --stdin
. Vous pouvez éventuellement spécifier--no-filters
pour vous assurer qu'aucune conversion crlf ne se produit, ou spécifier--path=somethi.ng
de laisser git utiliser le filtre spécifié viagitattributes
(également @ user420667). Et-w
pour soumettre réellement le blob.git/objects
(si vous êtes dans un dépôt git).echo -e 'blob 16\0Hello, \r\nWorld!' | shasum
==echo -e 'Hello, \r\nWorld!' | git hash-object --stdin --no-filters
et il sera également équivalent avec\n
et 15.echo
ajoute une nouvelle ligne à la sortie, qui est également passée dans git. C'est pourquoi ses 14 personnages. Pour utiliser l'écho sans nouvelle ligne, écrivezecho -n 'Hello, World!'
Je ne fais que développer la réponse
@Leif Gruenwoldt
et détailler ce qui se trouve dans la référence fournie par@Leif Gruenwoldt
Fais le toi-même..
Comment GIT calcule ses hachages de commit
Le texte
blob⎵
est un préfixe constant et\0
est également constant et est leNULL
caractère. Les<size_of_file>
et<contents_of_file>
varient en fonction du fichier.Voir: Quel est le format de fichier d'un objet git commit?
Et c'est tout le monde!
Mais attendez! , avez-vous remarqué que le
<filename>
n'est pas un paramètre utilisé pour le calcul de hachage? Deux fichiers peuvent potentiellement avoir le même hachage si leur contenu est le même indépendamment de la date et de l'heure de création et de leur nom. C'est l'une des raisons pour lesquelles Git gère mieux les déplacements et les renomme que les autres systèmes de contrôle de version.Faites-le vous-même (Ext)
Remarque:
Le lien ne mentionne pas comment l'
tree
objet est haché. Je ne suis pas certain de l'algorithme et des paramètres, mais d'après mon observation, il calcule probablement un hachage basé sur tous lesblobs
ettrees
(leurs hachages probablement) qu'il contientla source
SHA1("blob" + <size_of_file>
- y a-t-il un espace supplémentaire entre le blob et la taille? La taille est-elle décimale? Est-il préfixé par zéro?git hash-object
C'est un moyen rapide de vérifier votre méthode de test:
Production:
où
sha1sum
est dans GNU Coreutils.Ensuite, il s'agit de comprendre le format de chaque type d'objet. Nous avons déjà couvert le trivial
blob
, voici les autres:la source
$(printf "\0$s" | wc -c)
. Notez le caractère vide ajouté. Autrement dit, si la chaîne est 'abc' avec le caractère vide ajouté devant, la longueur donnerait 4, pas 3. Ensuite, les résultats avec sha1sum correspondent à git hash-object.Basé sur la réponse de Leif Gruenwoldt , voici un substitut de la fonction shell à
git hash-object
:Tester:
la source
J'en avais besoin pour certains tests unitaires dans Python 3, alors j'ai pensé le laisser ici.
Je m'en tiens aux
\n
fins de ligne partout, mais dans certaines circonstances, Git peut également changer vos fins de ligne avant de calculer ce hachage, vous pouvez donc en avoir besoin.replace('\r\n', '\n')
.la source