Хэши SHA1, хранящиеся в объектах дерева (возвращенные git ls-tree
), не соответствуют хешам SHA1 содержимого файла (возвращаемым sha1sum
)
$ git cat-file blob 4716ca912495c805b94a88ef6dc3fb4aff46bf3c | sha1sum
de20247992af0f949ae8df4fa9a37e4a03d7063e -
Как git вычисляет хэши файлов? Сжимает ли он контент перед вычислением хеша?
Ответы:
$ echo -e 'blob 14\0Hello, World!' | shasum 8ab686eafeb1f44702738c8b0f24f2567c36da6d
Источник: http://alblue.bandlem.com/2011/08/git-tip-of-week-objects.html
источник
echo 'Hello, World!' | git hash-object --stdin
. При желании вы можете указать,--no-filters
что преобразование crlf не происходит, или--path=somethi.ng
разрешить git использовать фильтр, указанный черезgitattributes
(также @ user420667). И-w
действительно отправить blob.git/objects
(если вы находитесь в репозитории git).echo -e 'blob 16\0Hello, \r\nWorld!' | shasum
==,echo -e 'Hello, \r\nWorld!' | git hash-object --stdin --no-filters
и это также будет эквивалентно\n
и 15.echo
добавляет к выводу новую строку, которая также передается в git. Вот почему в нем 14 символов. Чтобы использовать эхо без новой строки, напишитеecho -n 'Hello, World!'
Я только расширяю ответ
@Leif Gruenwoldt
и детализирую то, что указано в ссылке, предоставленной@Leif Gruenwoldt
Сделай сам..
Как GIT вычисляет хэши коммитов
Текст
blob⎵
является постоянным префиксом, а\0
также постоянным иNULL
символом. Значения<size_of_file>
и<contents_of_file>
различаются в зависимости от файла.См .: Каков формат файла объекта фиксации git?
И все, ребята!
Но ждать! , вы заметили, что
<filename>
это не параметр, используемый для вычисления хэша? Два файла потенциально могут иметь одинаковый хэш, если их содержимое одинаково безразлично к дате и времени создания и их имени. Это одна из причин, по которой Git обрабатывает перемещение и переименование лучше, чем другие системы контроля версий.Сделай сам (Ext)
Примечание:
В ссылке не упоминается, как
tree
хешируется объект. Я не уверен в алгоритме и параметрах, однако, по моим наблюдениям, он, вероятно, вычисляет хэш на основе всехblobs
иtrees
(вероятно, их хешей), которые он содержитисточник
SHA1("blob" + <size_of_file>
- есть ли дополнительный пробел между blob и размером? Размер десятичный? Это с нулевым префиксом?git hash-object
Это быстрый способ проверить свой метод тестирования:
Вывод:
где
sha1sum
находится в GNU Coreutils.Затем все сводится к пониманию формата каждого типа объекта. Мы уже рассмотрели тривиальное
blob
, вот другие:источник
$(printf "\0$s" | wc -c)
. Обратите внимание на добавленный пустой символ. То есть, если строка 'abc' с добавленным пустым символом впереди, длина даст 4, а не 3. Тогда результаты с sha1sum будут соответствовать git hash-object.Основываясь на ответе Лейфа Грюнвольдта , вот функция оболочки, заменяющая
git hash-object
:Тест:
источник
Мне это было нужно для некоторых модульных тестов в Python 3, поэтому я решил оставить его здесь.
Я
\n
везде придерживаюсь окончаний строк, но в некоторых случаях Git может также изменить окончание строк перед вычислением этого хэша, поэтому вам может понадобиться и.replace('\r\n', '\n')
там.источник