Commit - самый «лицо проекта» объект Git. Когда говорят «коммит» - имеют в виду этот объект. Содержит:
- SHA tree - снимок всех файлов проекта на этот момент.
- SHA родителей - один (обычно), ноль (root commit) или два-и-более
(merge commit).
- Автор - имя, email, время.
- Коммиттер - имя, email, время. Обычно совпадает с автором.
- Сообщение коммита.
Посмотреть руками:
git cat-file -p HEAD
# tree 7e3f9a2b1c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f
# parent a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0
# author Имя Фамилия <email@example.com> 1716817381 +0300
# committer Имя Фамилия <email@example.com> 1716817381 +0300
#
# README с описанием проекта
Снимок, не дельта
Коммит хранит ссылку на tree, то есть полный снимок проекта на этот момент. Не разницу с предыдущим коммитом. Разница вычисляется на лету между 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 <SHA первого родителя>
parent <SHA второго родителя>
author ...
committer ...
Merge branch 'feature' into main
Кол-во родителей теоретически не ограничено (octopus merge). Практически - почти всегда два.