# git commit _Ежедневная работа · GitLab Knowledge Base_ **TL;DR:** Фиксирует то, что лежит в индексе, как новый коммит-объект и передвигает текущую ветку на этот коммит. Без аргументов открывает редактор для сообщения; чаще всего вызывают с `-m`. `git commit` - момент, когда «правки» становятся «историей». Берёт снимок индекса (не рабочего дерева!) и упаковывает в [commit](/courses/git/kb/commit.md)-объект. ## Что происходит при коммите 1. Из индекса собирается tree-объект (через `write-tree`). 2. Создаётся commit-объект: tree + родитель (HEAD) + author + committer + сообщение. Author - кто написал изменения, committer - кто их зафиксировал; обычно совпадают, но при rebase/cherry-pick/apply от patch'а committer обновляется, а author остаётся прежним. 3. Текущая ветка двигается на новый коммит-SHA. 4. HEAD автоматически следует за веткой. Подробный разбор - в главе 4 учебника (plumbing). ## Базовые формы ```bash git commit # откроет редактор для сообщения git commit -m "fix typo" # короткое inline-сообщение git commit -m "title" -m "body" # title + пустая строка + body git commit -a # auto-stage всех отслеживаемых # файлов (как git add -u + commit) git commit --amend # переписать последний коммит ``` ## --amend Самый частый специальный режим. Не создаёт новый коммит, а *переписывает* HEAD-коммит. Используется, чтобы: - добавить забытый файл (`git add forgot.js && git commit --amend`) - исправить сообщение (`git commit --amend -m "новый текст"`) - оставить сообщение, но обновить содержимое (`git commit --amend --no-edit`) После `--amend` старая версия коммита остаётся в `.git/objects/` как dangling - `git reflog` её увидит ещё месяц. **Важно**: если коммит уже запушен - `--amend` создаст конфликт при следующем push. Либо `push --force-with-lease`, либо новый коммит вместо amend. ## Сообщение коммита Конвенция, родившаяся в Linux kernel и принятая большинством: ``` area: краткое описание в повелительном наклонении Более подробный текст, если нужен. Что и почему, не как - код сам про «как». Перенос по 72 символа. Closes #123 ``` Первая строка ≤ 50 символов, в повелительном (`add`, `fix`, не `added` или `adds`). Пустая строка. Тело - если нужно объяснить мотивацию или предупредить о тонкостях. ## Подводные камни - `git commit` коммитит **индекс**, а не рабочее дерево. Если забыл `git add` - изменения не попадут. - `git commit -am "..."` (через `-a`) автостейджит **только изменённые отслеживаемые файлы**. Новые untracked-файлы не попадут. Их всегда надо `git add` явно. - Пустой коммит не пройдёт без флага. Если нужно (например, для тэгирования) - `git commit --allow-empty -m "release v1.0"`. ## Команды ```bash git commit -m "..." ``` Зафиксировать индекс с inline-сообщением ```bash git commit -a -m "..." ``` Astage все отслеживаемые + закоммитить (новые файлы не попадут) ```bash git commit --amend --no-edit ``` Подмешать индекс в последний коммит, не меняя сообщения ```bash git commit --allow-empty -m "release" ``` Создать коммит без изменений (для тегов, маркеров релиза) ## См. также - [git add](/courses/git/kb/add.md) - [git status](/courses/git/kb/status.md) - [git log](/courses/git/kb/log.md) - [Commit](/courses/git/kb/commit.md)