Люди делают коммиты, как бог на душу положит. Это становится очевидно, даже если совсем немного почитать истории коммитов на GitHub.

git rebase

Я не буду распространяться о том, как писать комментарии к коммитам. У меня на эту тему есть отдельный пост. Сегодня мы обсудим не менее важный вопрос: когда именно нужно делать коммиты. Меня об этом постоянно спрашивают на конференциях. Так часто, что я выработал два правила, которые теперь постоянно использую.

Итак, я делаю коммиты, когда:

  • выполнил единицу работы
  • сделал изменения, которые потом может потребоваться отменить

Всякий раз, когда рабочая ситуация подходит под одно из этих условий, я фиксирую изменения с помощью коммита. На всякий случай уточняю: я делаю по коммиту на каждый случай. То есть, если я внес изменения, которые потом придется отменить, и при этом сделал изменения, которые составляют законченную единицу работы, нужно два коммита. Один – для единицы работы, другой – для изменений, которые будут отменены в будущем.

Думаю, что второе правило довольно понятное. С него и начнем. В процессе работы вы обязательно будете делать изменения с расчетом на то, что потом точно их отмените. Это может быть временный программный компонент, патч или что-нибудь еще, что скоро удалят. В таких случаях я подтверждаю изменения отдельным коммитом. Так потом легче отыскать эти изменения и отменить их с помощью git revert. Меня столько раз выручал этот метод, что даже для изменений, в судьбе которых я просто не уверен, я все равно делаю отдельный коммит.

С этим разобрались, теперь возвращаемся к первому правилу.

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

Проблема в том, что люди по-разному понимают, что такое единица работы.

Чтобы в этом разобраться, давайте для начала решим, что ей не является.

Единица работы абсолютно точно не зависит от потраченного времени. Делать коммиты раз в сколько-то минут, часов или дней просто-напросто нелепо. В этом случае история версии будет выглядеть как хронология событий, и никакой другой пользы от нее не будет. Да, коммиты с префиксом WIP делать можно. Но если я их увижу в истории ветки master, вам не сдобровать!

Отдельные типы изменений тоже не стоит принимать за единицу работы. Делать коммиты для новых файлов отдельно от коммитов для измененных файлов чаще всего бессмысленно.

Впрочем, это касается любой типизации, будь то код (JavaScript или HTML), слой (Клиент или API) или расположение (например, файловая система).

Выходит, под единицей работы не стоит понимать ни потраченное время, ни тип изменений. Что же это тогда?

Я думаю, в основе тут лежит функционал (feature). У функционала больше контекста, поэтому с ее помощью намного проще измерить единицу работы. Обычно в этот контекст входят и время, и тип, и суть изменений. Если вы будете привязывать единицу работы к функционалу, ваши коммиты начнут рассказывать последовательную историю.

Так почему бы не перефразировать первое правило: Я делаю коммит, когда я заканчиваю работать над функционалом?

Думаю, этот тот самый случай, когда обстоятельства имеют значение. Даже в рамках одного и того же репозитория под функционалом может пониматься множество разных вещей. А еще функционал различается по размеру. Поэтому оперируя понятием «единица работы», вы оставляете себе свободу контролировать размер этой единицы. Вам просто нужно уметь её мерить. Я для себя решил, что если делать это с помощью функционала, коммиты получаются идеальные.

Перевод оригинальной статьи: «When to make a Git Commit» by Jason McCreary