← назад к разделу

Коммит — единица истории. Через полгода именно по коммитам вы (или коллега) будете разбираться, что и зачем менялось. Разница между историей-помощником и историей-помойкой — в ремесле: что класть в коммит, как его подписывать и что в репозиторий не пускать вообще.

Атомарный коммит: одно изменение — один снимок

Хороший коммит — атомарный: одно логическое изменение целиком. Починили баг — коммит; отформатировали код — отдельный коммит; добавили функцию — третий. Плохие крайности: «коммит-свалка» (баг + рефакторинг + новая фича в одном) и коммит «сохранился на всякий случай» с половиной недописанной мысли.

Зачем это: атомарные коммиты можно по одному откатывать, переносить между ветками и понимать при ревью. Свалку — только целиком.

Точность набора обеспечивает индекс:

git add src/OrderService.java      # только нужные файлы
git add -p                          # интерактивно: по кусочкам внутри файла!
git commit -m "fix: пересчёт суммы при удалении последней позиции"

git add -p — недооценённая команда: она показывает изменения кусками и спрашивает, какие включить. Так из одного файла с двумя правками собираются два чистых коммита.

Сообщение коммита: ответ на вопрос «зачем»

Первая строка — короткое резюме (до ~70 символов), в повелительном наклонении, без точки. Что именно изменилось — видно из кода; сообщение должно отвечать на то, чего в коде нет: зачем.

  • Плохо: fix, правки, wip, изменил OrderService.
  • Хорошо: fix: сумма корзины не обнулялась при удалении последней позиции.

Многие команды используют префиксы conventional commits (feat:, fix:, refactor:, docs:) — по ним удобно фильтровать историю и собирать changelog автоматически. Если нужно больше контекста — пустая строка после резюме и абзац подробностей.

Читать историю: log, diff, blame

git log --oneline -15        # последние 15 коммитов кратко
git log -p file.txt          # история конкретного файла с изменениями
git diff                     # что изменено, но ещё не в индексе
git diff --staged            # что уже в индексе (войдёт в коммит)
git show abc123              # что сделал конкретный коммит
git blame OrderService.java  # кто и в каком коммите менял каждую строку

git blame звучит обвиняюще, но это инструмент археологии, а не поиска виноватых: нашли странную строку → blame → коммит → его сообщение объясняет «зачем» → а если нет, известно, кого спросить. Связка «diff перед коммитом» — привычка, отсекающая случайные изменения: секунда просмотра спасает от закоммиченного отладочного вывода.

.gitignore: чему в истории не место

Git предлагает коммитить всё, что видит, — но не всё должно попадать в репозиторий:

build/          # артефакты сборки — воспроизводятся из кода
node_modules/   # зависимости — восстанавливаются из lock-файла
*.log           # логи
.idea/          # настройки IDE
.env            # СЕКРЕТЫ — никогда в git!

Файл .gitignore в корне проекта перечисляет такие пути — Git перестаёт их замечать. Два правила. Первое: игнорируется генерируемое и личное, коммитится исходное и общее. Второе, важнейшее: секреты (пароли, ключи API) не должны попадать в историю никогда — история распределённая и вечная, удалить из неё по-настоящему трудно; попавший в коммит ключ считается скомпрометированным и подлежит ротации. Про автоматическую защиту от этого — Gitleaks в цикле безопасности.

Поправить последний коммит

Забыли файл или опечатались в сообщении — не создавайте коммит «fix предыдущего»:

git add забытый-файл.txt
git commit --amend           # заменит последний коммит новым

Осторожность одна: --amend переписывает коммит — безопасно, пока он не отправлен на сервер. Правило «не переписывать отправленное» подробно разобрано в статье про rebase.

Коротко

  • Атомарный коммит: одно логическое изменение. git add -p собирает коммит по кусочкам.
  • Сообщение отвечает «зачем»: короткое резюме, при нужде — подробности абзацем. Префиксы feat/fix помогают фильтровать.
  • История — инструмент: log для ленты, diff перед коммитом, blame для археологии.
  • .gitignore: сборка, зависимости, IDE-файлы — вон; секреты — никогда в git, попали — ротация.
  • --amend чинит последний коммит, пока он не отправлен.

Что почитать дальше

  • Ветки и слияние — следующая тема цикла.
  • Отмена и спасение — reset, revert и reflog, когда что-то пошло не так.
  • Что такое Git — если пропустили начало.