Все ли объекты дерева сделаны при коммите? - PullRequest
1 голос
/ 06 марта 2020

Мне интересно, что:

  1. Все ли дерево объект сделан, когда совершено (возможно commit-tree в сантехнике?).
  2. Тогда почему дерево объекты (особенно для каталогов) не создаются при добавлении в индекс, тогда как blob являются?

Я выяснил, blob сделаны когда я добавляю файлы в индекс.

git init
mkdir test-dir
echo "File1" > test-dir/test.txt
git count-objects
# 0 objects, 0 kilobytes
git add test-dir/test.txt
git count-objects
# 1 objects, 4 kilobytes
git ls-files -s
# 100644 03f128cf48cb203d938805e9f3e13b808d1773e9 0       test-dir/test.txt

Но я не могу найти дерево объект для test-dir до фиксации.

git commit -m "my first commit"
# [master (root-commit) 48448a5] my first commit
# 1 file changed, 1 insertion(+)
# create mode 100644 test-dir/test.txt
git count-objects
# 4 objects, 16 kilobytes
git rev-list --all --objects
# 48448a5c6d04cbcd6ab25b64c4bbab9dec5fcf94
# 5f618720e3fc14d396086feb6ee1d869fbbf2e21
# 3bdfe0bec6b5140848283e5e55fc0edd9bb52b32 test-dir
# 03f128cf48cb203d938805e9f3e13b808d1773e9 test-dir/test.txt
git cat-file -t 3bdfe0
# tree
git cat-file -p 3bdfe0
# 100644 blob 03f128cf48cb203d938805e9f3e13b808d1773e9    test.txt

Теперь я получаю дерево объект для test-dir каталога.

1 Ответ

2 голосов
/ 06 марта 2020

Объекты дерева строятся по git write-tree. То есть git commit состоит из нескольких подкоманд (см. Примечания ниже):

git write-tree
git commit-tree <parents> <message> <tree-hash-ID>
git update-ref <full-ref> <commit-hash-ID>

Первая команда, которая не принимает параметров, превращает index (используйте git ls-files --stage просмотреть его содержимое) в виде серии древовидных объектов. Идентификатор ha sh объекта дерева верхнего уровня выводится на его стандартный вывод.

Для второй команды требуются параметры: -p для каждого родительского коммита ha sh ID, -m или -F для предоставьте сообщение журнала фиксации и дерево с sh ID, напечатанным git write-tree. В качестве стандартного вывода он генерирует идентификатор ha sh объекта фиксации.

Последней команде также нужны параметры: полное имя текущей ветви (например, refs/heads/master) или имя HEAD, если HEAD в настоящее время отсоединен от любой ветви, и идентификатор ha sh, созданный второй командой. Он обновляет данный ref для хранения данного идентификатора ha sh. Если ссылка является именем ветви, или HEAD, идентификатор ha sh должен быть идентичным коммиту.

Примечания

Первоначально git commit был небольшим сценарием оболочки, который просто запустили эти три команды (с соответствующим клеем оболочки). В то время у git commit было не так много опций, флагов и режимов, как сейчас.

В итоге git commit превратилось в одну C программу. Теперь он делает все эти части внутри. Он также обрабатывает блокировку, запускает ловушки предварительной фиксации и другие подобные вещи; это не может быть сделано должным образом в сценарии оболочки с использованием трех отдельных команд. Однако три отдельные команды все еще остаются, так что вы можете использовать их для создания своих собственных сценариев, если хотите.

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