#git-objects-four-types
Четыре типа объектов в Git. Что хранит каждый и как они связаны?
Что отвечать
`blob` - содержимое одного файла, без имени и прав. `tree` - список записей одной директории: права, тип, SHA, имя. Запись tree указывает либо на blob (файл), либо на другой tree (поддиректория) - получается рекурсивное дерево. `commit` - SHA корневого tree плюс метаданные: родитель(и), автор, коммиттер, дата, сообщение. `tag` - именованный указатель на коммит, обычно с подписью.
Что хотят услышать
Senior должен: - назвать что Git это key-value store: ключ это SHA, значение это zlib-сжатый объект в `.git/objects/` - объяснить рекурсию tree: дерево директорий это дерево tree-объектов - сказать что blob не знает имени файла - имя живёт в tree, который на blob ссылается - объяснить почему ветка это просто файл с одним SHA в `.git/refs/heads/<name>`, а HEAD это файл с указателем на ветку - различить annotated tag (объект в `.git/objects/`) и lightweight tag (просто запись в `.git/refs/tags/`)
Подводные камни
- ✗ Сказать «commit хранит изменения» - на самом деле commit хранит полный snapshot через tree, diff Git вычисляет на лету
- ✗ Сказать «blob знает имя файла» - не знает, имя добавляется tree-объектом
- ✗ Перепутать tag-объект с веткой - оба ref, но tag обычно не двигается, ветка двигается
Follow-up
- ? Что покажет `git cat-file -p HEAD^{tree}`?
- ? Где физически лежит ветка `feature/x`?
- ? Чем lightweight tag отличается от annotated в плане объектов?
Глубина в базе знаний