# git commit --amend _Ежедневная работа · GitLab Knowledge Base_ **TL;DR:** Переписывает последний коммит - меняет сообщение, подмешивает забытые правки, поправляет содержимое. Создаёт новый объект с новым SHA. Безопасен до push, опасен после. `git commit --amend` не создаёт новый коммит - *заменяет* последний. Точнее, создаёт новый коммит с обновлённым содержимым и двигает ветку на него. Старый коммит остаётся в `.git/objects/` как dangling. ## Что можно делать ### Поправить сообщение ```bash git commit --amend -m "новый текст сообщения" # или без -m откроется редактор с текущим сообщением git commit --amend ``` ### Добавить забытый файл ```bash git add forgot.js git commit --amend --no-edit # --no-edit оставит старое сообщение, файл подмешается в коммит ``` ### Поправить содержимое Если только что закоммитил и заметил баг - поправь файл, застейджи, `--amend`. Получишь правильный коммит вместо «фикс предыдущего коммита» отдельным коммитом. ## Что физически происходит 1. Берётся текущий индекс (включая новые правки, если есть). 2. Создаётся новый commit-объект: - tree: из текущего индекса - parent: тот же, что был у старого коммита (не текущий коммит!) - author/committer/message: из старого + правки 3. Текущая ветка двигается на новый SHA. 4. Старый коммит становится dangling. Старый коммит ещё месяц виден в reflog. Если ошибся в amend - можно восстановить через `git reflog`. ## Когда нельзя Если коммит уже запушен и кто-то его подтянул - amend ломает историю. У тебя локально один SHA, у других - другой. Обычный push откажет: ``` ! [rejected] feature -> feature (non-fast-forward) ``` Варианты: - **Force-push** через `--force-with-lease`. Безопасно только для feature-ветки, которую кроме тебя никто не смотрит. - **Не amend'ить**, сделать новый коммит. Правильно для `main`/`master`/общих веток. Правило: amend разрешён до первого push. После push - только на личных ветках и только с force-with-lease. ## Подводные камни - **Author-date.** `--amend` оставляет author-date старым, но committer-date обновляет. `git log --pretty=fuller` покажет обе. - **Подписи (GPG).** Если коммит был подписан - после `--amend` подпись слетит. Повторно `git commit --amend -S`. - **Время.** `git log` сортирует по committer-date по умолчанию. После amend коммит «всплывает» наверх, даже если author-date старый. ## Команды ```bash git commit --amend -m "new text" ``` Поменять сообщение последнего коммита ```bash git commit --amend --no-edit ``` Подмешать индекс в последний коммит, не меняя сообщения ```bash git push --force-with-lease ``` Запушить после amend; безопаснее --force ```bash git commit --amend --date="now" ``` Обновить и author-date до текущего момента ## См. также - [git commit](/courses/git/kb/commit-cmd.md) - [Interactive rebase](/courses/git/kb/interactive-rebase.md) - [git reflog](/courses/git/kb/reflog.md)