Что такое commit в git и из чего он состоит
Что проверяют
Знаете ли вы, что коммит это объект в хранилище со строго определённым набором полей, а не «сохранённый набор изменений». Разница всплывает на первом же практическом вопросе про перебазирование, слияние или изменение истории.
Как отвечать
Коммит это неизменяемый объект, который содержит ссылку на дерево, то есть на полный снимок отслеживаемых файлов на момент фиксации; ссылки на родительские коммиты, которых ноль у самого первого, один у обычного и два или больше у слияния; автора с временем создания изменений; коммиттера с временем записи; сообщение и, если настроена подпись, саму подпись.
Идентификатор коммита это хеш его содержимого, исторически SHA-1, в современных версиях доступен и SHA-256. Хеш не хранится внутри объекта, а вычисляется из всех перечисленных полей, включая родителя. Поэтому изменение сообщения или пересадка на другого родителя порождает новый коммит, а вся последующая цепочка получает новые идентификаторы.
Стоит подчеркнуть: git хранит снимки, а не патчи. Дифф, который показывает git show, вычисляется на лету сравнением деревьев коммита и его родителя. Автор и коммиттер это разные поля: при перебазировании и переносе коммита автор сохраняется, а коммиттер меняется на того, кто выполнил операцию.
Где спотыкаются
Говорят «коммит хранит изменения», а потом не могут объяснить, почему после правки одного старого коммита у всех следующих меняются хеши. Из модели снимков и хеширования родителя это следует сразу, из модели патчей не следует никак.
Тащат в коммит результаты сборки и настройки среды: каталоги с классами и пакетами, локальные файлы среды разработки, подключённые библиотеки бинарниками. Репозиторий распухает навсегда, потому что удаление в новом коммите не убирает объект из истории.
Смешивают в одном коммите правку логики и переформатирование всего модуля. Ревью становится нечитаемым, а построчная история авторства теряется: git blame показывает того, кто запустил автоформат, вместо того, кто написал строку.