Что такое commit в git и из чего он состоит
Что проверяют
Понимаете ли вы внутреннее устройство коммита, а не только команду его создания. Вопрос простой на входе, но ответ быстро показывает, работал ли человек с историей всерьёз: разбирал конфликты, переносил правки, чинил испорченную ветку.
Как отвечать
Коммит это объект хранилища, состоящий из ссылки на дерево с полным снимком отслеживаемых файлов, ссылок на родителей (ноль у первого коммита, один у обычного, два и более у слияния), полей автора и коммиттера с датами, сообщения и необязательной подписи. Имя объекта это хеш его содержимого, исторически SHA-1, в современных версиях поддерживается и SHA-256.
Важная деталь: хранятся снимки, а не разницы. Одинаковое содержимое файла в разных коммитах это один и тот же объект, поэтому снимки не раздувают хранилище так, как кажется на первый взгляд. Разница между версиями считается при просмотре.
Отсюда же понятно, почему история переписывается только созданием новых объектов. Исправление сообщения, перебазирование, объединение коммитов не меняют старый объект, а создают новый с другим хешем, и ветка начинает указывать на него. Старые объекты какое-то время остаются доступны по журналу ссылок.
Где спотыкаются
Фиксируют всё подряд без разбора. В историю попадают кеши байт-кода, каталог виртуального окружения, локальные файлы с ключами и паролями. Последнее особенно неприятно: удаление секрета следующим коммитом не отменяет утечку, ключ придётся отзывать.
Коммитят тетради целиком, вместе с выводом ячеек и счётчиками запусков. Каждый прогон даёт огромный шумный дифф, слияние превращается в ручную склейку, а ревью по существу становится невозможным. Лечится очисткой вывода перед фиксацией.
Исключают из истории файлы фиксации зависимостей, считая их сгенерированными. Именно они и обеспечивают воспроизводимость окружения, тогда как каталог установленных пакетов не нужен никому. Путаница между «сгенерировано» и «не нужно хранить» стоит команде плавающих сборок.