# Tree _Объектная модель · GitLab Knowledge Base_ **TL;DR:** Объект Git, который хранит список того, что лежит в одной директории: записи `(права, тип, SHA, имя)`. Рекурсивно ссылается на другие tree для поддиректорий. Tree - объект, который описывает содержимое одной директории. Каждая строка tree - это одна запись: ``` 100644 blob 5f7e9c12... README.md 100644 blob 8a3f2e91... index.html 040000 tree e2b5a91f... images 100644 blob b1d4a7e0... style.css ``` Четыре колонки: - **Права доступа** - `100644` обычный файл, `100755` исполняемый, `040000` поддиректория, `120000` симлинк, `160000` gitlink (submodule). Git хранит mode как число, `git ls-tree` всегда печатает шестью цифрами с ведущим нулём. - **Тип** - `blob` для файла, `tree` для поддиректории. - **SHA** - указатель на сам blob или tree. - **Имя** - как файл/папка называется в этой директории. Содержимое файла лежит в [blob](/courses/git/kb/blob.md). Tree связывает имя с этим содержимым. ## Рекурсивная структура Tree, в котором есть запись типа `tree`, указывает на другой tree-объект для поддиректории. Получается дерево из tree-объектов, отражающее дерево директорий проекта: ``` корневой tree ├── blob README.md ├── tree images/ │ ├── blob logo.png │ └── blob banner.jpg └── blob style.css ``` ## Когда создаётся При `git commit`. До коммита tree не существует - есть только `.git/index`, который хранит плоский список путей. `git write-tree` превращает индекс в иерархию tree-объектов и возвращает SHA корневого. ## Посмотреть содержимое ```bash git cat-file -p git ls-tree HEAD # tree последнего коммита git ls-tree -r HEAD # рекурсивно, плоский список всех файлов ``` ## Дедупликация на уровне дерева Если поддиректория не изменилась между двумя коммитами - tree этой поддиректории идентичен. Tree родителя ссылается на тот же SHA. То есть Git дедуплицирует не только файлы, но и целые поддиректории. ## Команды ```bash git cat-file -p HEAD^{tree} ``` Содержимое tree последнего коммита ```bash git ls-tree HEAD ``` Список tree корневой директории последнего коммита ```bash git ls-tree -r HEAD ``` Рекурсивно все файлы из tree ```bash git write-tree ``` Собрать tree из текущего индекса ## См. также - [Blob](/courses/git/kb/blob.md) - [Commit](/courses/git/kb/commit.md) - [SHA-1 в Git](/courses/git/kb/sha1.md)