Читая пост в блоге, я познакомился с синтаксисом master^{tree}
в git cat-file -p master^{tree}
, используемом для печати объекта дерева, соответствующего ветви master
(commit).
Технически это не имеет ничего общего с git cat-file
.
Суффикс ^{<em>type</em>}
, где type
- это любой из четырех типов объектов Git - tag
, commit
, tree
или blob
- фактически является директивой для анализатора ревизий. Эти директивы описаны в документации gitrevisions .
Сам парсер редакции может быть вызван отдельно, например, с помощью git rev-parse
:
git rev-parse master^{tree}
. Вот результат клона репозитория Git для Git:
$ git rev-parse master
d61d20c9b413225793f8a0b491bbbec61c184e26
$ git rev-parse master^{tree}
a09123ee85e55b1de2e3c70c43588f10d885cacb
, который показывает, как master^{tree}
относится к другому идентификатору ha sh, чем master
. Используя git cat-file -t
, мы можем понять, почему это так:
$ git cat-file -t master
commit
$ git cat-file -t master^{tree}
tree
Объект d61d20c9b413225793f8a0b491bbbec61c184e26
является объектом фиксации, а объект a09123ee85e55b1de2e3c70c43588f10d885cacb
является a объект дерева Поэтому, когда мы просим git cat-file
напечатать содержимое этого объекта (с -p
), мы получаем либо содержимое коммита, либо содержимое дерева.
Могу ли я использовать это синтаксис для печати больших двоичных объектов в этом дереве?
No.
Сам объект фиксации содержит такие данные:
$ git cat-file -p master | sed 's/@/ /'
tree a09123ee85e55b1de2e3c70c43588f10d885cacb
parent d2ea03ddeeeab6f703290af30ba89d5606858673
author Junio C Hamano <gitster pobox.com> 1588202142 -0700
committer Junio C Hamano <gitster pobox.com> 1588202142 -0700
The fifth batch
Signed-off-by: Junio C Hamano <gitster pobox.com>
Есть несколько важных фоновые элементы, которые нужно знать здесь:
Каждый объект коммитов должен содержать ровно один объект дерева. Это дерево представляет моментальный снимок фиксации.
Каждое имя ветви ограничено разрешением до идентификатора ha sh существующего коммита.
Поэтому, если master
решит совершить га sh H , мы всегда сможем найти одно и только одно дерево га sh T и так. Git поэтому позволяет master^{tree}
, который говорит Git: найти объект, идентифицируемый по имени, а затем делать все, что требуется, чтобы найти объект дерева из этого объекта . Это всегда работает, потому что имя является именем ветви, которое преобразуется в коммит, который содержит ровно одно дерево.
Деревья, однако, обычно содержат много поддеревьев и / или много больших двоичных объектов. В вашем случае показанное вами дерево содержит четыре записи:
100644 blob 980a0d5f19a64b4b30a87d4206aade58726b60e3 hello-world
100644 blob 6bbf1b1052278a9507b22f1cac84503a05eb935c package.json
100644 blob e82dbc14b98ed7d67e88381d58732b00459c180f random-file
100644 blob b07036b6d12da665c096d9fe3b4d8e3551147e31 some-file
Чтобы преобразовать дерево в указанную c запись в пределах этого дерева, мы должны представить синтаксический анализатор ревизий с помощью name .
В моем случае дерево, связанное с именем ветви master
, после преобразования из объекта коммита в объект дерева, содержит сотни имен (wc -l
сообщает 459 имен) , Вот последние десять:
$ git cat-file -p master^{tree} | tail
100644 blob 95851b85b6b7181130f0cd441c2bd7ac0bfb89da wrap-for-bin.sh
100644 blob 3a1c0e052677dca8d1bc19121d609e0c226e88ee wrapper.c
100644 blob eab8c8d0b9aab55c8435b9f451efd81e715131f8 write-or-die.c
100644 blob 6e69877f25791632d98bf7b109a2eaebd04c96af ws.c
100644 blob 98dfa6f73f9d7cd41867f97fdae41bd4dc5ec2a1 wt-status.c
100644 blob 73ab5d4da1c0b4766cb63501b9db06c0a7fea934 wt-status.h
100644 blob 4d20069302b25a133869380bd685e921ddc0bacc xdiff-interface.c
100644 blob 93df26900c2bfa923f1e871924ef319a6786fa72 xdiff-interface.h
040000 tree 82fc725b3f0affab0f034a80baaf9e589b870942 xdiff
100644 blob d594cba3fc9d82d94b9277e886f2bee265e552f6 zlib.c
Чтобы преобразовать из master
в дерево, скажем, в пятно, которое это дерево имеет для zlib.c
, мы должны включить буквальную строку zlib.c
:
$ git rev-parse master:zlib.c
d594cba3fc9d82d94b9277e886f2bee265e552f6
Это относится даже к объекту дерева, который содержит только одну запись; <em>hash</em>^{blob}
допускается только в том случае, если hash
уже разрешается в объект BLOB-объекта.
Этот же синтаксис работает с большинством команд Git, включая git cat-file
:
$ git cat-file -t master:zlib.c
blob
Внимательно прочитайте документацию gitrevision. Здесь содержится огромное количество информации, представленной в сравнительно нескольких словах.