Git: как отменить последний коммит — reset, revert, amend
Чтобы отменить последний коммит в Git и сохранить изменения, выполните git reset --soft HEAD~1. Если коммит уже отправлен на сервер, используйте git revert HEAD: он не переписывает историю.
Какой способ выбрать
Ситуация | Команда | Что станет с изменениями |
|---|---|---|
Коммит только локальный, изменения нужны |
| Остаются в индексе (staged) |
Коммит только локальный, хочу пересобрать индекс |
| Остаются в рабочей папке, не в индексе |
Коммит только локальный, изменения не нужны |
| Удаляются |
Коммит уже на сервере (push выполнен) |
| Создаётся новый коммит, отменяющий старый |
Опечатка в сообщении или забыт файл |
| Добавляются в тот же коммит |
Отменить коммит и сохранить изменения
HEAD~1 означает «на один коммит назад от текущего». Сам коммит исчезнет из истории ветки, а правки останутся у вас.
# изменения остаются в индексе — можно сразу делать новый git commit
git reset --soft HEAD~1
# изменения остаются в рабочей папке, но не добавлены в индекс
git reset HEAD~1Режим --mixed используется по умолчанию, поэтому git reset HEAD~1 и git reset --mixed HEAD~1 делают одно и то же. Новые файлы после такой отмены отображаются как неотслеживаемые (?? в git status --short).
Отменить коммит и удалить изменения
git reset --hard HEAD~1Если вы отменили коммит по ошибке, его ещё можно вернуть: git хранит записи о перемещениях HEAD в журнале reflog.
git reflog # найдите строку с нужным коммитом, например HEAD@{1}
git reset --hard HEAD@{1} # вернуться к состоянию до отменыСразу после reset в ORIG_HEAD хранится прежнее положение ветки, поэтому часто достаточно git reset --hard ORIG_HEAD.
Отменить коммит, который уже отправлен на сервер
Если коллеги могли забрать ваш коммит, историю переписывать нельзя. git revert создаёт новый коммит с обратными изменениями, и история остаётся целой.
git revert HEAD # откроет редактор для сообщения нового коммита
git revert --no-edit HEAD # оставить сообщение по умолчанию
git pushЕсли всё же нужно убрать коммит из удалённой ветки (например, в личной ветке, которую никто не использует), перепишите историю и отправьте её принудительно с защитой от перезаписи чужой работы:
git reset --soft HEAD~1
git push --force-with-leaseИсправить последний коммит вместо отмены
Если нужно лишь поправить сообщение или добавить забытый файл, отменять коммит не требуется.
git commit --amend -m "Новое сообщение коммита" # изменить сообщение
git add forgotten-file.txt
git commit --amend --no-edit # добавить файл в тот же коммитamend тоже переписывает историю, поэтому для уже отправленных коммитов действуют те же ограничения, что и для reset.
Как проверить результат
git status --short # что осталось в индексе и рабочей папке
git log --oneline -3 # последние три коммитаЧастые вопросы
Как отменить последний коммит, но оставить файлы на диске?
Выполните git reset HEAD~1. Коммит исчезнет, а файлы останутся изменёнными в рабочей папке.
Как отменить несколько последних коммитов?
Укажите нужное число: git reset --soft HEAD~3 отменит три последних коммита и сохранит все их изменения в индексе.
Можно ли вернуть коммит после git reset --hard?
Обычно да, пока он не удалён сборщиком мусора: найдите его хеш в git reflog и выполните git reset --hard <хеш>. Незакоммиченные правки, потерянные из-за --hard, этим способом не восстановить.
Чем отличаются reset и revert?
reset переносит указатель ветки назад и убирает коммит из истории. revert добавляет новый коммит, отменяющий старый, и безопасен для общих веток.