Почему git hash-object возвращает другой хеш, чем openssl sha1? - PullRequest
43 голосов
/ 13 марта 2011

Контекст: я загрузил файл (Audirvana 0.7.1.zip) из code.google на свой Macbook Pro (Mac OS X 10.6.6).

Я хотел проверитьконтрольная сумма, которая для этого конкретного файла размещена как 862456662a11e2f386ff0b24fdabcb4f6c1c446a (SHA-1).git hash-object дал мне другой хеш, но openssl sha1 вернул ожидаемый:

$ echo A > foo.txt
$ cat foo.txt
A
$ git hash-object foo.txt 
f70f10e4db19068f79bc43844b49f3eece45c4e8
$ openssl sha1 foo.txt 
SHA1(foo.txt)= 7d157d7c000ae27db146575c08ce30df893d3a64

Что происходит?

Ответы [ 3 ]

55 голосов
/ 13 марта 2011

Вы видите разницу, потому что git hash-object не просто берет хеш байтов в файле - он добавляет строку «blob», за которой следуют размер файла и NUL, до содержимого файла перед хэшированием.В этом другом ответе есть более подробная информация о переполнении стека:

Или,чтобы убедить себя, попробуйте что-то вроде:

$ echo -n hello | git hash-object --stdin
b6fc4c620b67d95f953a5c1c1230aaab5db5a1b0

$ printf 'blob 5\0hello' > test.txt
$ openssl sha1 test.txt
SHA1(test.txt)= b6fc4c620b67d95f953a5c1c1230aaab5db5a1b0
4 голосов
/ 13 марта 2011

Дайджест SHA1 рассчитывается по строке заголовка, за которой следуют данные файла.Заголовок состоит из типа объекта, пробела и длины объекта в байтах в десятичном виде.Это отделяется от данных нулевым байтом.

Итак:

$ git hash-object foo.txt
f70f10e4db19068f79bc43844b49f3eece45c4e8
$ ( perl -e '$size = (-s shift); print "blob $size\x00"' foo.txt \
               && cat foo.txt ) | openssl sha1
f70f10e4db19068f79bc43844b49f3eece45c4e8

Одним из следствий этого является то, что «пустое дерево» и «пустой» BLOB имеют разные идентификаторы.То есть:

e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 всегда означает «пустой файл».потому что он распознается как особый случай и никогда не сохраняется (в современных версиях Git).Напротив, если вы добавите в репозиторий пустой файл, будет сохранен блоб «e69de29bb2d1d6434b8b29ae775ad8c2e48c5391».

2 голосов
/ 13 марта 2011

Ответ лежит здесь:

Как назначить Git SHA1 для файла без Git?

git вычисляет метаданные файла + содержимое, а не только содержимое.

На данный момент это достаточно хороший ответ, и вывод заключается в том, что git не является инструментом для загрузки контрольной суммы.

...