Открыть сервисСервис

Коммит в системах контроля версий

Коммит (от англ. commit — «совершать, фиксировать») — базовая операция в системах контроля версий (SCM), представляющая собой атомарное сохранение набора изменений в файловом дереве с созданием уникальной точки в истории проекта. Каждый коммит фиксирует состояние всех отслеживаемых файлов на определённый момент, сопровождается уникальным идентификатором (обычно в форме короткого хеша SHA-1 или SHA-256), автором, отметкой времени и комментарием, описывающим суть изменений. Коммиты образуют связанную цепочку, формирующую историю проекта, и позволяют откатываться к любому сохранённому состоянию, сравнивать версии и объединять параллельную работу нескольких разработчиков.

Основные системы контроля версий

Коммит как операция реализована в большинстве современных SCM. Наиболее распространённые из них:

СистемаТипОсобенности коммитов
GitраспределённаяКоммиты хранятся локально, идентификатор — SHA-хеш содержимого
MercurialраспределённаяКоммит с числовым номером, локальное хранение
Subversion (SVN)централизованнаяКоммит — отправка изменений на сервер, глобальный номер ревизии
CVSцентрализованнаяКоммит пофайловый, без единого номера ревизии
BazaarраспределённаяКоммит с локальным идентификатором

В распределённых системах (Git, Mercurial) коммиты создаются локально и не требуют подключения к серверу; их синхронизация с общим репозиторием выполняется отдельными командами push и pull. В централизованных системах (SVN, CVS) коммит обычно означает немедленную отправку изменений в центральный репозиторий, доступный всем участникам.

Устройство коммита в Git

Git — наиболее популярная на сегодня система контроля версий, и именно в ней коммит имеет наиболее проработанную структуру. Коммит в Git — это объект, содержащий:

  • ссылку на родительский коммит (или несколько родительских при слиянии);
  • корень дерева файлов (tree-объект), описывающий полное состояние проекта;
  • автора и коммитора (часто одно и то же лицо);
  • временную метку с часовым поясом;
  • сообщение коммита;
  • собственный SHA-1 хеш, вычисляемый из всех этих данных.

Типичный цикл работы с коммитами в Git включает три шага:

  1. Изменение файлов — редактирование исходного кода, конфигураций, документации.
  2. Индексация (stage) — команда git add помещает выбранные изменения в промежуточную область (staging area, индекс).
  3. Фиксация — команда git commit создаёт новый коммит из содержимого индекса.

Такая трёхшаговая модель даёт возможность формировать осмысленные коммиты, включающие только логически завершённые изменения, даже если в рабочем каталоге одновременно присутствуют правки по нескольким задачам.

Идентификатор коммита

В Git каждый коммит получает уникальный 40-символьный SHA-1 хеш, вычисляемый из содержимого коммита, дерева и родительских ссылок. На практике для краткости используется первые 7–12 символов хеша. Хеш является детерминированным: одинаковое содержимое всегда даёт одинаковый идентификатор, что обеспечивает целостность истории — любое изменение старого коммита неизбежно меняет хеши всех последующих.

В Subversion коммиты нумеруются монотонно возрастающими целыми числами (ревизии), причём номер присваивается центральным сервером. В Mercurial используется гибрид: локальный числовой идентификатор, дополняемый SHA-хешем.

Сообщение коммита

Сообщение коммита — текстовое описание, поясняющее, что и зачем было изменено. Качественное сообщение — важная часть культуры работы с версиями. Существуют устоявшиеся соглашения:

  • Первая строка — краткое резюме (обычно до 50 символов), в повелительном наклонении («Добавить обработку ошибок»).
  • Пустая строка, затем подробное описание мотивов и деталей при необходимости.
  • Конвенциональные коммиты (Conventional Commits) — формат, где первая строка начинается с типа: feat:, fix:, docs:, refactor:, test: и т. д. Этот стандарт позволяет автоматически генерировать журнал изменений и определять версию по семантическому версионированию.

Слияние и ветвление

Коммиты тесно связаны с моделью ветвления. Каждая ветка в Git — это ссылка на определённый коммит; при добавлении нового коммита ветка перемещается вперёд. Операция слияния (merge) создаёт новый коммит с двумя или более родителями, объединяя истории двух веток. При конфликтах слияния Git требует ручного разрешения перед созданием итогового коммита.

Отдельной разновидностью является «rebase» — перенос коммитов из одной ветки на другую с созданием их копий (новых хешей) и изменением родительской цепочки. Это позволяет поддерживать линейную историю ценой изменения идентификаторов.

Откат и исправление

Git допускает отмену последствий коммита несколькими способами:

  • git revert — создаёт новый коммит, инвертирующий изменения указанного;
  • git reset — перемещает указатель ветки на более ранний коммит (с сохранением, очисткой или переносом изменений в рабочий каталог);
  • git commit --amend — заменяет последний коммит, изменяя его содержимое или сообщение (создаётся новый хеш).

Первые два способа безопасны для уже опубликованной истории; amend и rebase меняют хеши и потому не рекомендуются для коммитов, отправленных в общий репозиторий.

Практические принципы

Существует ряд общепринятых практик работы с коммитами:

  • Атомарность — каждый коммит должен содержать одно логически завершённое изменение.
  • Инвертируемость — коммит по возможности должен легко откатываться.
  • Регулярность — фиксация на каждом завершённом этапе работы, а не «гигантский» коммит в конце дня.
  • Читаемая история — предпочтение небольших осмысленных коммитов перед массовыми правками.

Эти принципы легли в основу методологий непрерывной интеграции, где автоматизированные сборки и тесты запускаются на каждом коммите.

История термина

Операция фиксации изменений существовала ещё в ранних SCM: RCS (1982), SCCS (1972) и CVS (1986) использовали понятие «commit» или его эквиваленты. С появлением BitKeeper и随后 Git (создан Линусом Торвальдсом в 2005 году для разработки ядра Linux) коммит приобрёл распределённый характер и стал центральной единицей истории проекта.

Заметили ошибку или не согласны с информацией в статье? Напишите нам support@bfometr.ru