Проектная лаборатория
Собственный Git
Этап 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 go2. Откройте папку в IDE
cd ./my-gitРеализуйте требования этапа в созданном проекте.
Запустите из папки проекта
node '/opt/graphlms/tools/project-lab/cli.mjs' submit --stage kp1Запускайте submit из папки проекта. Это локальные проверки, а не сертификаты или результаты аккаунта CodeCrafters.
Результат проверки
go / ЛОКАЛЬНОПодключение к локальной проверке…
Здесь появится результат
Запустите submit в терминале. Страница обновляет результаты каждые 8 секунд.