Pourquoi git hash-object renvoie-t-il un hash différent de openssl sha1?
contexte: j'ai téléchargé un fichier (Audirvana 0.7.1.zip) à partir du code.google à mon Macbook Pro (Mac OS X 10.6.6).
je voulais vérifier le total de contrôle, qui pour ce fichier particulier est affiché comme 862456662a11e2f386ff0b24fdabcb4f6c1c446a (SHA-1). git hash-object
m'a donné un hachage différent, mais openssl sha1
a retourné le 862456662a11e2f386ff0b24fdabcb4f6c1c446a attendu.
L'expérience suivante semble exclure toute possible corruption de téléchargement ou différences newline et pour indiquer qu'Il ya effectivement deux algorithmes différents en jeu:
$ echo A > foo.txt
$ cat foo.txt
A
$ git hash-object foo.txt
f70f10e4db19068f79bc43844b49f3eece45c4e8
$ openssl sha1 foo.txt
SHA1(foo.txt)= 7d157d7c000ae27db146575c08ce30df893d3a64
que se passe-t-il?
3 réponses
vous voyez une différence parce que git hash-object
ne prend pas seulement un hachage des octets dans le fichier - il prépare la chaîne de caractères "blob" suivie de la taille du fichier et un NULL au contenu du fichier avant le hachage. Il y a plus de détails dans cette autre réponse sur le débordement de la pile:
Ou, pour vous en convaincre, essayez quelque chose comme:
$ echo -n hello | git hash-object --stdin
b6fc4c620b67d95f953a5c1c1230aaab5db5a1b0
$ printf 'blob 5"151900920"hello' > test.txt
$ openssl sha1 test.txt
SHA1(test.txt)= b6fc4c620b67d95f953a5c1c1230aaab5db5a1b0
le sha1 digest est calculé sur une chaîne d'en-tête suivie par les données du fichier. L'en-tête se compose du type d'objet, d'un espace et de la longueur de l'objet en octets (décimal). Il est séparé de données par un octet nul.
:
$ git hash-object foo.txt
f70f10e4db19068f79bc43844b49f3eece45c4e8
$ ( perl -e '$size = (-s shift); print "blob $size\x00"' foo.txt \
&& cat foo.txt ) | openssl sha1
f70f10e4db19068f79bc43844b49f3eece45c4e8
une conséquence de cela est que" l'arbre "vide et" le " blob vide ont des identifiants différents. C'est-à-dire:
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 signifie toujours " vide fichier" 4b825dc642cb6eb9a060e54bf8d69288fbee4904 signifie toujours "répertoire vide "
vous trouverez que vous pouvez en fait faire git ls-tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904
dans un nouveau dépôt git sans objets enregistrés, car il est reconnu comme un cas spécial et jamais réellement stocké (avec des versions Git modernes). En revanche, si vous ajoutez un fichier vide à votre déclaration, un blob "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391" sera stocké.
la réponse se trouve ici:
comment affecter un git SHA1 à un fichier sans git?
git
calcule les métadonnées du fichier + le contenu, pas seulement le contenu.
C'est une bonne réponse pour le moment, et le fait est que git
n'est pas l'outil pour vérifier les téléchargements.