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

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

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

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

Чтение объекта-дерева

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

На этом этапе вы реализуете команду git ls-tree, предназначенную для просмотра объекта-дерева.

Объекты-деревья

На этом этапе мы познакомимся со следующим типом объектов Git — деревьями.

Деревья хранят структуру каталогов.

Объект-дерево содержит несколько записей. Каждая включает:

  • Хеш SHA-1, указывающий на blob-объект или дерево.
    • Для файла он указывает на blob-объект.
    • Для каталога — на дерево.
  • Имя файла или каталога.
  • Режим файла или каталога.
    • Это упрощённая версия прав доступа файловой системы Unix.
    • Для файлов допустимы значения:
      • 100644 (обычный файл).
      • 100755 (исполняемый файл).
      • 120000 (символическая ссылка).
    • Для каталогов используется 40000.
    • Для подмодулей существуют другие значения, но в этом задании мы с ними не работаем.

Например, для такой структуры каталогов:

your_repo/
  - file1
  - dir1/
    - file_in_dir_1
    - file_in_dir_2
  - dir2/
    - file_in_dir_3

Записи объекта-дерева будут выглядеть так:

40000 dir1 <tree_sha_1>
40000 dir2 <tree_sha_2>
100644 file1 <blob_sha_1>
  • Строка 1 (40000 dir1 <tree_sha_1>) означает, что dir1 — каталог с хешем SHA <tree_sha_1>.
  • Строка 2 (40000 dir2 <tree_sha_2>) означает, что dir2 — каталог с хешем SHA <tree_sha_2>.
  • Строка 3 (100644 file1 <blob_sha_1>) означает, что file1 — обычный файл с хешем SHA <blob_sha_1>.

dir1 и dir2 сами будут объектами-деревьями, записи которых описывают вложенные файлы и каталоги.

Команда ls-tree

Команда git ls-tree служит для просмотра объекта-дерева.

Для такой структуры каталогов:

your_repo/
  - file1
  - dir1/
    - file_in_dir_1
    - file_in_dir_2
  - dir2/
    - file_in_dir_3

Вывод git ls-tree будет следующим:

$ git ls-tree <tree_sha>
040000 tree <tree_sha_1>	dir1
040000 tree <tree_sha_2>	dir2
100644 blob <blob_sha_1>	file1

Обратите внимание: вывод отсортирован по алфавиту — именно так Git хранит записи внутри объекта-дерева.

На этом этапе вы реализуете команду git ls-tree с флагом --name-only. С флагом --name-only вывод выглядит так:

$ git ls-tree --name-only <tree_sha>
dir1
dir2
file1

Тестирующая система использует --name-only, поскольку этот формат проще проверять.

Рекомендуем также реализовать полный вывод ls-tree: это потребует разобрать все данные объекта-дерева, а не только имена файлов.

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

Как и blob-объекты, деревья хранятся в каталоге .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 blob-объекта или дерева (не в шестнадцатеричном формате).

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

Тесты

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

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

Затем запишет объект-дерево в каталог .git/objects.

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

$ /path/to/your_program.sh ls-tree --name-only <tree_sha>

Она проверит, что вывод программы соответствует содержимому объекта-дерева.

Для такой структуры каталогов:

your_repo/
  - file1
  - dir1/
    - file_in_dir_1
    - file_in_dir_2
  - dir2/
    - file_in_dir_3

Ожидается следующий вывод:

dir1
dir2
file1

Примечания

  • В файле объекта-дерева хеши SHA-1 представлены не шестнадцатеричными строками, а просто необработанными байтами (длиной 20 байт).
  • В файле объекта-дерева записи отсортированы по имени. Вывод ls-tree следует тому же порядку.

Проверка в вашей 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 kp1

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

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

go / ЛОКАЛЬНО

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

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

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

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