2012-06-11 3 views
1

Я знаком с how Git creates SHA1 hashes for files (blobs), но не так, как они созданы для объектов тегов. Я предполагаю, что они, если я создаю аннотированный тег, но что такое рецепт? И как я могу реплицировать его за пределами Git (например, в Perl или Python)?Как создан объект SHA1 Git Tag?

ответ

0

Узор в основном:

sha1("tag " + datasize + "\0" + data) 

Где data является выход git cat-file. Можно производить это по конвейеру, что выход на git-hash-object так:

git cat-file tag v0.30 | git hash-object -t tag --stdin 

и эквивалент Perl-один-лайнер:

git cat-file tag v0.30 | perl -MDigest::SHA1 -E '$/=undef;$_=<>;say Digest::SHA1->new->add("tag ".length()."\0".$_)->hex digest' 

кажется, что можно сделать, это то же самое с любым из типы объектов, просто заменив "tag " на правильное имя объекта: "blob ", "tree ", или "commit ".

0

Это почти то же самое, хотя маленький заголовок, добавленный к объекту фиксации, отличается. Вы можете использовать git cat-file, чтобы увидеть фактический формат.

+0

Ах, я вижу, вывод 'git cat-file' возвращает содержимое, которое на самом деле хэшируется. – theory

1

Содержание в тега объекта выглядит следующим образом:

object <commit-sha1> 
type commit 
tag <tag-name> 
tagger <author-with-timestamp> 

<tag-message> 

На основе этого текста вычисляется значение SHA1.

Как я могу воспроизвести его за пределами Git (например, в Perl или Python)?

Посмотрите на libgit2 и его различные bindings.

+0

Удивительный. Где? Я нашел [блог sha1 код в pygit2] (https://github.com/libgit2/pygit2/blob/master/test/utils.py#L54), но не для тегов. И мой ack-foo должен быть неадекватным для libgit2 ... – theory

+0

Ничего, я понял это через эксперименты. См. Мой ответ. – theory