git commit
Зафиксировать содержимое индекса как новый коммит в репозитории
Описание
git commit создаёт новый коммит — снимок состояния индекса в определённый момент времени. Коммит содержит: хеш дерева файлов, ссылку на родительский коммит (или несколько при слиянии), имя и email автора, имя и email коммитера, временную метку и сообщение коммита. Каждый коммит идентифицируется уникальным SHA-1 (или SHA-256) хешем.
Коммиты — основа истории Git. Они неизменны: созданный коммит нельзя «отредактировать» в привычном смысле. git commit --amend создаёт новый коммит с новым хешем. Именно поэтому переписывание опубликованных коммитов опасно — оно ломает историю у всех, кто работает с тем же remote.
Хорошее сообщение коммита — важная профессиональная практика. Стандарт Conventional Commits предписывает формат тип(скоуп): описание. Строка заголовка — не более 72 символов, тело сообщения (при необходимости) — через пустую строку, объясняет «зачем», а не «что».
Синтаксис
- ОПЦИИ — флаги, управляющие поведением (см. таблицу).
- <путь> — если указан, коммитить только изменения в этих путях (без явного
git add).
Флаги и опции
| Флаг | Описание |
|---|---|
-m <сообщение> | Задать сообщение коммита прямо в командной строке. Можно использовать несколько раз для заголовка и тела. |
-a / --all | Автоматически добавить в индекс все изменения отслеживаемых файлов перед коммитом. Новые untracked файлы не включаются. |
--amend | Заменить последний коммит новым, включая текущий индекс и (опционально) новое сообщение. Создаёт коммит с новым хешем. |
--no-edit | При --amend оставить сообщение коммита без изменений, не открывая редактор. |
-v / --verbose | Показать diff в редакторе сообщения коммита — для удобного написания описания по контексту изменений. |
--allow-empty | Создать коммит даже если индекс не содержит изменений. Используется для тегирования событий, trigger CI и т.п. |
--allow-empty-message | Создать коммит с пустым сообщением (не рекомендуется в обычной работе). |
-C <коммит> | Использовать сообщение и метаданные существующего коммита как есть. |
-c <коммит> | Как -C, но открыть редактор для правки сообщения. |
--date=<дата> | Переопределить дату автора коммита. Формат: ISO 8601, RFC 2822 или относительный (yesterday). |
--author=<автор> | Переопределить автора коммита: "Name <email>". |
-S / --gpg-sign | Подписать коммит GPG-ключом. Ключ определяется из user.signingKey. |
--no-gpg-sign | Создать коммит без GPG-подписи, даже если commit.gpgSign = true в конфиге. |
--squash=<коммит> | Создать коммит с сообщением для последующего squash через git rebase --autosquash. |
--fixup=<коммит> | Создать fixup-коммит для последующего squash с целевым коммитом через git rebase --autosquash. |
Паттерны использования
Conventional Commits — стандарт сообщений
# Новая функциональность git commit -m "feat(auth): add OAuth2 login with Google" # Исправление бага git commit -m "fix(api): handle null response from payment gateway" # Рефакторинг git commit -m "refactor(db): extract repository pattern" # Документация git commit -m "docs: update API reference for v2 endpoints"
Коммит с подробным телом
git commit -m "feat(billing): add invoice generation" \ -m "Implements PDF generation using WeasyPrint. Closes #142. Breaking change: requires INVOICE_TEMPLATE_DIR env variable." # Или через редактор (git commit без -m) # В редакторе: # feat(billing): add invoice generation # [пустая строка] # Implements PDF generation...
Исправить последний коммит
# Опечатка в сообщении — исправить git commit --amend -m "feat(auth): add JWT token refresh" # Добавить забытый файл в последний коммит git add forgotten-file.py git commit --amend --no-edit # ВАЖНО: не делайте --amend для опубликованных коммитов!
fixup/squash — чистая история в PR
# Нашли ошибку в коммите abc1234 — создаём fixup git add src/fix.py git commit --fixup=abc1234 # Сообщение будет: "fixup! feat(auth): original message" # Перед merge — склеить все fixup-коммиты git rebase -i --autosquash main
Коммит от имени другого автора
# Закоммитить от имени другого разработчика git commit --author="Maria Ivanova" \ -m "feat(ui): add dark mode toggle" # Co-authored-by в теле сообщения (GitHub распознаёт) git commit -m "feat: pair programming result" \ -m "Co-authored-by: Maria Ivanova "
Пустой коммит для trigger CI
# Запустить CI без реальных изменений git commit --allow-empty -m "ci: retrigger pipeline" # Зафиксировать событие (деплой, тег версии) git commit --allow-empty -m "chore: mark production deploy v2.3.1"
Советы и подводные камни
Создайте файл
~/.gitmessage с шаблоном (тип, скоуп, описание) и подключите его:git config --global commit.template ~/.gitmessageПри вызове
git commit редактор откроется с готовым шаблоном — не нужно вспоминать формат каждый раз.
Флаг
-v помещает полный diff ниже линии разделителя в окне редактора. Это позволяет видеть изменения при написании сообщения — нет нужды переключаться в другое окно.
--amend создаёт коммит с новым хешем. Если коммит уже запушен в shared ветку и кто-то успел на него опереться — --amend + принудительный push сломает чужие локальные репозитории. Используйте --amend только для коммитов, которые ещё не запушены, или работаете в одиночку.