# Commit _Объектная модель · GitLab Knowledge Base_ **TL;DR:** Объект Git: снимок состояния всего проекта (через tree) плюс метаданные - автор, коммиттер, дата, родители, сообщение. SHA коммита включает SHA родителя, что делает историю криптографически связанной. Commit - самый «лицо проекта» объект Git. Когда говорят «коммит» - имеют в виду этот объект. Содержит: - **SHA tree** - снимок всех файлов проекта на этот момент. - **SHA родителей** - один (обычно), ноль (root commit) или два-и-более (merge commit). - **Автор** - имя, email, время. - **Коммиттер** - имя, email, время. Обычно совпадает с автором. - **Сообщение коммита**. Посмотреть руками: ```bash git cat-file -p HEAD # tree 7e3f9a2b1c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f # parent a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0 # author Имя Фамилия 1716817381 +0300 # committer Имя Фамилия 1716817381 +0300 # # README с описанием проекта ``` ## Снимок, не дельта Коммит хранит ссылку на [tree](/courses/git/kb/tree.md), то есть полный снимок проекта на этот момент. Не разницу с предыдущим коммитом. Разница вычисляется на лету между tree этого коммита и tree родителя. ## SHA включает родителя SHA коммита считается от его собственного содержимого, включая SHA родителя. Это значит: если в каком-то старом коммите хоть что-то изменилось - у всех его потомков сменятся SHA. Подделать «один старый коммит, оставив всё после него» невозможно. Это даёт криптографическую гарантию целостности истории. SHA любого коммита - это, по сути, хэш всей истории до него. ## Автор vs коммиттер *Автор* - кто написал изменения. *Коммиттер* - кто положил их в репозиторий. Чаще совпадают. Расходятся при: - `git cherry-pick` - автор остаётся изначальный, коммиттер - кто cherry-pick'нул. - `git rebase` - автор не меняется, коммиттер становится текущим. - Применение патча через `git am` от чужого автора. Видно обе даты так: `git log --pretty=fuller`. ## Merge-коммит Merge-коммит - это просто коммит с несколькими родителями. Внутри: ``` tree ... parent parent author ... committer ... Merge branch 'feature' into main ``` Кол-во родителей теоретически не ограничено (octopus merge). Практически - почти всегда два. ## Команды ```bash git cat-file -p HEAD ``` Содержимое коммита HEAD ```bash git commit-tree ``` Создать коммит из tree (plumbing) ```bash git log --pretty=fuller ``` Показать обе даты - автора и коммиттера ```bash git log --pretty=format:'%H %an %s' ``` Кастомный формат вывода истории ## См. также - [Tree](/courses/git/kb/tree.md) - [Blob](/courses/git/kb/blob.md) - [Tag](/courses/git/kb/tag.md) - [SHA-1 в Git](/courses/git/kb/sha1.md)