Проектная лаборатория

Собственный Git

0 / 7этапов пройдено

Этап 05 · Основные этапы

Запись объекта-дерева

Русский перевод заданий CodeCrafters. Примеры подготовлены для Go. Выбор языка меняет команды и результаты, но не текст задания.

На этом этапе вы реализуете запись дерева в каталог .git/objects.

Хранение объектов-деревьев: повторение

Напомним: объекты-деревья хранят структуру каталогов и сохраняются в каталоге .git/objects.

Например, если хеш дерева равен e88f7a929cd70b0274c4ea33b209c97fa845fdbc, его путь будет .git/objects/e8/8f7a929cd70b0274c4ea33b209c97fa845fdbc.

Файл объекта-дерева выглядит следующим образом (до сжатия Zlib):

tree <size>\0
<mode> <name>\0<20_byte_sha>
<mode> <name>\0<20_byte_sha>

(В блоке выше для удобства чтения добавлены переводы строк, но в настоящем файле их нет.)

  • Файл начинается с tree <size>\0. Это заголовок объекта, устроенный так же, как заголовок blob-объекта.
  • После заголовка идёт несколько записей. Каждая имеет формат <mode> <name>\0<sha>:
    • <mode> задаёт тип и права доступа файла или каталога.
    • <name> — имя файла или каталога.
    • \0 обозначает нулевой байт.
    • <20_byte_sha> — 20-байтовый хеш SHA-1 файла или каталога.

Поле <mode>

Поле <mode> задаёт тип и права доступа каждой записи. Среди допустимых значений:

  • 100644 — обычный файл.
  • 100755 — исполняемый файл.
  • 40000 — каталог (объект-дерево).

Обратите внимание: режим каталога — 40000, а не 040000. Хотя команды Git, например git ls-tree, для удобства чтения показывают его как 040000, в объекте-дереве хранится 40000.

Подробнее о внутреннем формате объекта-дерева можно прочитать здесь.

Команда git write-tree

Команда git write-tree создаёт объект-дерево из текущего состояния «области подготовленных изменений» (индекса). В эту область изменения попадают после выполнения git add.

В этом задании вы не будете реализовывать индекс. Вместо этого считайте, что все файлы рабочего каталога уже подготовлены к коммиту.

Пример использования git write-tree:

# Create a file with some content
$ echo "hello world" > test.txt
 
# Add the file to the staging area (we won't implement a staging area in this challenge)
$ git add test.txt
 
# Write the tree to .git/objects
$ git write-tree
4b825dc642cb6eb9a060e54bf8d69288fbee4904

Команда git write-tree выводит 40-символьный хеш SHA-1 объекта-дерева, записанного в .git/objects.

Для реализации git write-tree нужно:

  1. Перебрать файлы и каталоги в рабочем каталоге.
  2. Для файла создать blob-объект и сохранить его хеш SHA-1.
  3. Для каталога рекурсивно создать объект-дерево и сохранить его хеш SHA-1.
  4. Отсортировать все записи по имени в алфавитном порядке.
  5. Собрав все записи и их хеши SHA-1, записать объект-дерево в каталог .git/objects.

Если вы локально сравниваете результат с git, обязательно выполните git add . перед git write-tree, чтобы подготовить все файлы рабочего каталога.

Тесты

Тестирующая система инициализирует новый репозиторий Git вашей программой:

$ mkdir test_dir && cd test_dir
$ /path/to/your_program.sh init

Затем создаст несколько случайных файлов и каталогов:

$ echo "hello world" > test_file_1.txt
$ mkdir test_dir_1
$ echo "hello world" > test_dir_1/test_file_2.txt
$ mkdir test_dir_2
$ echo "hello world" > test_dir_2/test_file_3.txt

После этого запустит программу следующим образом:

$ /path/to/your_program.sh write-tree
4b825dc642cb6eb9a060e54bf8d69288fbee4904

Вы должны записать весь рабочий каталог в виде объекта-дерева и вывести его 40-символьный хеш SHA-1 в stdout.

Тестирующая система проверит, что вывод совпадает с хешем SHA-1 дерева, которое записала бы официальная реализация git.

Примечания

  • Не забудьте исключить каталог .git при создании записей дерева и отсортировать все записи по имени в алфавитном порядке.
  • Ваша реализация git write-tree должна поддерживать вложенные каталоги. Здесь полезна рекурсия: чтобы создать дерево родительского каталога, нужно создать деревья всех подкаталогов.
  • Наша реализация git write-tree немного отличается от официальной. Официальная реализация git определяет содержимое дерева по индексу. Мы считаем, что все файлы рабочего каталога уже подготовлены.

Проверка в вашей IDE

Нужны Node.js, Git, Go 1.24+ для тестеров и инструменты выбранного языка. Тестеры загружаются и запускаются локально; отдельным проектам нужны дополнительные системные зависимости.

Настройка проекта и IDE

1. Создайте проект один раз

node '/opt/graphlms/tools/project-lab/cli.mjs' init git ./my-git --language go

2. Откройте папку в IDE

cd ./my-git

Реализуйте требования этапа в созданном проекте.

Запустите из папки проекта

node '/opt/graphlms/tools/project-lab/cli.mjs' submit --stage fe4

Запускайте submit из папки проекта. Это локальные проверки, а не сертификаты или результаты аккаунта CodeCrafters.

Результат проверки

go / ЛОКАЛЬНО

Подключение к локальной проверке…

Здесь появится результат

Запустите submit в терминале. Страница обновляет результаты каждые 8 секунд.

GraphLMS — инженерная лаборатория роста