Инструменты

Git: история, которую можно читать через год

31.08.2026 · TitarX · 👁 4

Через год после написания кода вы не вспомните, почему выбрали именно это решение. Git-история — единственное место, где это могло сохраниться. Обычно там написано «fix», «fix2» и «работает».

Атомарный коммит

Коммит должен содержать одно логически завершённое изменение — такое, которое можно откатить целиком, не задев ничего постороннего.

Практический признак: если в описании коммита приходится писать «и», скорее всего, это два коммита. «Добавил валидацию email и обновил зависимости» — точно два.

Отдельно стоит держать рефакторинг и изменение поведения. Когда переименование двухсот переменных смешано с правкой логики, увидеть эту правку в диффе невозможно — а именно её и нужно проверить на ревью.

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

Работает простая структура: короткая строка в повелительном наклонении, пустая строка, затем объяснение почему.

Исправить утечку соединений в пуле воркеров

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

Возврат перенесён в блок finally.

Тело сообщения — это то, чего нет в диффе. Дифф показывает, что изменилось; сообщение объясняет, зачем, и какие альтернативы были отвергнуты.

Merge или rebase

Спор бесконечный, но правило простое.

Rebase хорош для своей ветки, которую ещё никто не видел: он превращает историю в линейную последовательность и убирает шум промежуточных merge-коммитов.

Merge — для интеграции в общую ветку: он сохраняет факт, что работа велась параллельно, и не переписывает существующие коммиты.

Единственное жёсткое ограничение: не переписывайте историю, которую уже забрали другие. Rebase создаёт новые объекты с новыми хешами, и у коллег после этого расходится история.

Приведение ветки в порядок перед PR

Интерактивный rebase позволяет собрать серию «fix, fix2, ещё раз fix» в один осмысленный коммит:

git rebase -i origin/master

В открывшемся списке pick заменяется на squash (объединить с предыдущим), reword (переписать сообщение) или drop (выбросить). Порядок строк тоже можно менять.

Когда нужно найти, где сломалось

git bisect находит виновный коммит двоичным поиском — на истории в тысячу коммитов это около десяти проверок:

git bisect start
git bisect bad                 # текущее состояние сломано
git bisect good v1.4.0         # здесь работало

# Git переключается на середину; проверяем и отвечаем
git bisect good   # или git bisect bad

git bisect reset

Процесс автоматизируется, если проверка описывается командой:

git bisect run pytest tests/test_orders.py

Именно ради этого стоит держать коммиты атомарными: bisect укажет на коммит, и если тот меняет одну вещь, причина видна сразу.

Полезное в повседневной работе

# Кто и когда менял конкретные строки
git log -L 10,25:src/pricing.py

# Найти коммит по содержимому изменения
git log -S "calculate_discount" --oneline

# Отменить коммит, уже попавший в общую ветку, новым коммитом
git revert <hash>

# Временно отложить незакоммиченное
git stash push -m "черновик валидации"

Что в итоге

История коммитов — это документация, которую невозможно забыть обновить: она пишется одновременно с кодом. Атомарные коммиты и объяснение причин в сообщении стоят пары минут при написании и экономят часы через год — включая ваши собственные.