Можно ли использовать синтаксис `master ^ {tree}` `git cat-file -p` для печати больших двоичных объектов? - PullRequest
0 голосов
/ 30 апреля 2020

Читая пост в блоге, я познакомился с синтаксисом master^{tree} в git cat-file -p master^{tree}, используемом для печати объекта дерева, соответствующего ветви master (commit).

Можно ли использовать этот синтаксис также распечатать капли в этом дереве? Я пробовал следующие команды, которые не работают:

git cat-file -p master^{blob} и git cat-file -p master^{tree}^{blob}

На какой странице Git man я могу прочитать больше о master^{tree} синтаксис? Это не описано в git cat-file --help.

nlykkei:~/projects/demos/git-test (change-config)$ git cat-file -p master^{tree}
100644 blob 980a0d5f19a64b4b30a87d4206aade58726b60e3    hello-world
100644 blob 6bbf1b1052278a9507b22f1cac84503a05eb935c    package.json
100644 blob e82dbc14b98ed7d67e88381d58732b00459c180f    random-file
100644 blob b07036b6d12da665c096d9fe3b4d8e3551147e31    some-file
nlykkei:~/projects/demos/git-test (change-config)$ git cat-file -p master^{blob}
error: master^{blob}: expected blob type, but the object dereferences to tree type
fatal: Not a valid object name master^{blob}
nlykkei:~/projects/demos/git-test (change-config)$ git cat-file -p master^{tree}^{blob}
error: master^{tree}^{blob}: expected blob type, but the object dereferences to tree type
fatal: Not a valid object name master^{tree}^{blob}

1 Ответ

1 голос
/ 30 апреля 2020

Читая пост в блоге, я познакомился с синтаксисом 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. Здесь содержится огромное количество информации, представленной в сравнительно нескольких словах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...