Коммит — единица истории. Через полгода именно по коммитам вы (или коллега) будете разбираться, что и зачем менялось. Разница между историей-помощником и историей-помойкой — в ремесле: что класть в коммит, как его подписывать и что в репозиторий не пускать вообще.
Атомарный коммит: одно изменение — один снимок
Хороший коммит — атомарный: одно логическое изменение целиком. Починили баг — коммит; отформатировали код — отдельный коммит; добавили функцию — третий. Плохие крайности: «коммит-свалка» (баг + рефакторинг + новая фича в одном) и коммит «сохранился на всякий случай» с половиной недописанной мысли.
Зачем это: атомарные коммиты можно по одному откатывать, переносить между ветками и понимать при ревью. Свалку — только целиком.
Точность набора обеспечивает индекс:
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 — если пропустили начало.