git commit --amend: изменение последнего коммита
Вы только что сделали коммит и заметили опечатку в сообщении. Или забыли добавить один файл. git commit --amend позволяет исправить последний коммит — без создания нового. Это один из самых часто используемых инструментов ежедневной работы.
Что делает git commit –amend #
git commit --amend заменяет последний коммит новым. Технически старый коммит не изменяется — создаётся новый с другим хешем. Старый остаётся в reflog на 14 дней.
Команда позволяет:
- Изменить сообщение коммита
- Добавить забытый файл
- Убрать файл из коммита
- Изменить автора или email
- Изменить дату коммита
Изменить сообщение последнего коммита #
# Открыть редактор с текущим сообщением
git commit --amend
# Изменить сообщение напрямую без открытия редактора
git commit --amend -m "fix: исправить опечатку в форме входа"
# Проверить результат
git log --oneline -1
# def5678 fix: исправить опечатку в форме входа
Добавить забытый файл в коммит #
Самый частый сценарий: закоммитили, но забыли добавить один файл.
# Ситуация: сделали коммит, забыли добавить tests/auth.test.js
git log --oneline -1
# abc1234 feat: add authentication
git status
# Untracked files:
# tests/auth.test.js
# Добавить файл
git add tests/auth.test.js
# Добавить к последнему коммиту без изменения сообщения
git commit --amend --no-edit
# Теперь коммит включает тесты
git show --stat HEAD
# feat: add authentication
# src/auth.js | 45 +++
# tests/auth.test.js | 23 +++ ← теперь здесь
--no-edit сохраняет текущее сообщение без открытия редактора.
Убрать файл из коммита #
Случайно добавили в коммит не тот файл:
# Убрать файл из последнего коммита
git reset HEAD~ -- secrets.env
git commit --amend --no-edit
# Или через restore (Git 2.23+)
git restore --source=HEAD~ -- secrets.env
git add secrets.env # если нужно сохранить в рабочей директории
git commit --amend --no-edit
Изменить автора коммита #
# Изменить автора последнего коммита
git commit --amend --author="Правильное Имя <[email protected]>"
# Или обновить конфиг и применить
git config user.name "Правильное Имя"
git config user.email "[email protected]"
git commit --amend --reset-author --no-edit
Изменить дату коммита #
# Установить текущее время
git commit --amend --date=now --no-edit
# Установить конкретную дату
git commit --amend --date="2026-01-15 10:00:00 +0300" --no-edit
Amend после push: осторожно #
git commit --amend переписывает историю — хеш коммита изменяется. Если коммит уже запушен, потребуется принудительный push:
# После amend запушенного коммита
git push --force-with-lease origin feature/my-branch
# ⚠️ Никогда не делайте --force в ветках main/develop/master
# которые используют другие разработчики!
--force-with-lease безопаснее --force: он проверяет что никто другой не добавил коммиты в ветку пока вы работали.
Правило: amend безопасен только в личных ветках которые вы ещё не «шарили» с командой.
Использование git rebase -i для редактирования старых коммитов #
--amend работает только с последним коммитом. Для редактирования более ранних коммитов используйте git rebase -i:
# Редактировать последние 5 коммитов
git rebase -i HEAD~5
# Откроется редактор со списком коммитов:
# pick abc1234 feat: add user registration
# pick def5678 fix: validation logic
# pick ghi9012 docs: update README
# ...
# Замените 'pick' на нужную команду:
# pick — оставить коммит как есть
# reword — отредактировать сообщение (без изменения кода)
# edit — полностью отредактировать коммит (код и сообщение)
# squash — объединить с предыдущим коммитом
# Например:
# pick abc1234 feat: add user registration
# reword def5678 fix: validation logic ← изменит сообщение
# edit ghi9012 docs: update README ← позволит добавить файлы
# Сохранить и закрыть редактор (Ctrl+X в nano, :wq в vim)
# Git выполнит действия по очереди
После каждого шага вы можете:
- Добавить файлы:
git add file.txt - Продолжить:
git rebase --continue - Отменить весь rebase:
git rebase --abort
Отмена git commit –amend #
Если amendили но хотите вернуться назад:
# Посмотреть reflog (историю операций)
git reflog
# def5678 HEAD@{0}: commit (amend): fix: new message
# abc1234 HEAD@{1}: commit: fix: old message
# ...
# Вернуться на старый коммит
git reset --hard abc1234
# Теперь HEAD указывает на старый коммит с исходным сообщением
git log --oneline -1
# abc1234 fix: old message
git reflog хранит историю 14 дней, что даёт достаточно времени для восстановления.
Когда НЕ нужно использовать –amend #
Не используйте amend если:
- Коммит уже в удалённом репозитории и его видели другие разработчики
- Коммит в main или develop ветке
- Коммит слит (merged) в другую ветку
- Вы работаете в команде и коммит может быть основой для их работы
Почему опасно:
- Amend меняет хеш коммита
- У других разработчиков на локальной машине будет старая версия
- Они получат конфликты при pull’е
- Потребуется принудительный push который может потерять их работу
Правило: amend безопасен только в личных неопубликованных ветках.
Force push после amend #
Если всё же нужно запушить amended коммит в удалённый репо:
# ОПАСНО: полный force
git push --force origin feature/my-branch
# БЕЗОПАСНЕЕ: с проверкой
git push --force-with-lease origin feature/my-branch
# --force-with-lease проверит что никто другой
# не добавил коммиты пока вы работали
--force-with-lease намного безопаснее потому что отвергает push если удалённый репо изменился.
Полный пример рабочего сценария #
# Сделали коммит
git commit -m "feat: add user registration"
# Проверили — есть опечатка в сообщении и забыли добавить файл
git log --oneline -1
# abc1234 feat: add user registartion ← опечатка
git status
# Untracked: src/validators/email.js ← забытый файл
# Исправляем в два шага
git add src/validators/email.js
git commit --amend -m "feat: add user registration"
# Итог
git log --oneline -1
# def5678 feat: add user registration ← всё правильно
git show --stat HEAD
# feat: add user registration
# src/registration.js | 78 +++
# src/validators/email.js | 22 +++ ← добавлен
# Если уже запушили и нужно обновить удалённо
git push --force-with-lease origin feature/my-branch
Сценарий: исправление опечатки в опубликованном коммите #
# Коммит уже в remote и другие знают о нём
git push origin feature/my-branch
# Через время заметили опечатку в сообщении
git log --oneline -1
# abc1234 feat: add user registartion ← опечатка
# Вариант 1: создать новый коммит (безопасно для команды)
git commit --amend -m "feat: add user registration"
git push --force-with-lease origin feature/my-branch
# Требуется скоординировать с командой!
# Вариант 2: создать новый коммит-исправление (ещё безопаснее)
git commit -m "fix: correct spelling in previous commit message"
git push origin feature/my-branch
# Никого не затронет, история полная
# Вариант 3: если никто не знает о коммите
# (создана ветка но не поделились ссылкой)
git commit --amend -m "feat: add user registration"
git push --force-with-lease origin feature/my-branch
# Безопасно потому что никто не делал на основе этого
Часто задаваемые вопросы #
Почему после amend изменился хеш коммита? Amend создаёт новый объект-коммит с новым хешем. Старый коммит остаётся доступен через git reflog в течение 14 дней и может быть восстановлен. Git не удаляет коммиты сразу — это сборка мусора которая происходит редко.
Можно ли amendить не последний коммит? Нет, git commit --amend работает только с HEAD (последним коммитом). Для редактирования более ранних коммитов используйте git rebase -i HEAD~N. В rebase можно выбрать любой коммит для редактирования.
Amend изменил хеш, теперь push отклоняется. Что делать? Используйте git push --force-with-lease origin branch-name. Это перезаписывает историю на сервере. Важно: не делайте этого в общих ветках вроде main/develop без согласования с командой.
Как отменить amend если уже запушили? Найти старый хеш в reflog: git reflog найти нужный коммит, затем git reset --hard OLD_HASH. После этого push’ить: git push --force-with-lease. Используйте только если уверены что никто другой не полагается на новый коммит.
git commit –amend и git rebase -i — в чём разница? Amend только для последнего коммита, очень быстро. git rebase -i HEAD~5 даёт доступ к последним 5 коммитам: можно редактировать сообщение (reword), редактировать код (edit), объединять (squash), удалять (drop). Amend проще, rebase мощнее.
Почему –no-edit не открывает редактор? Флаг --no-edit значит что нужно использовать текущее сообщение коммита без изменений. Очень полезен когда добавляете файлы в коммит но сообщение правильное.
Может ли –amend повредить код? Нет. Amend только меняет сообщение или добавляет/убирает файлы. Содержимое файлов не изменяется. Всё что вы делали до amend остаётся на месте.
Что если я забыл про amend и создал новый коммит? Это не проблема — просто два коммита вместо одного. Можно потом merge’ить их через git rebase -i и squash, но это опасно если уже запушили.
Обработка amend в CI/CD #
В автоматизированных пайплайнах нужно быть осторожным с amended коммитами:
# В CI скриптах проверить что коммит не переписан
commit_hash=$(git rev-parse HEAD)
# Если в next run хеш изменился — значит amended
# Это может сломать кеширование и другие механизмы
Практические советы и трюки #
# Быстрое исправление без открытия редактора
git add file.txt
git commit --amend --no-edit
# Файл добавлен в последний коммит
# Изменить только сообщение, не файлы
git commit --amend -m "new message"
# Изменить автора последнего коммита
git commit --amend --author="Name <[email protected]>" --no-edit
# Просмотр того что будет изменено
git diff HEAD~1..HEAD # что в коммите
git show HEAD # весь коммит со всеми деталями
# Отмена всех staged изменений перед amend
git reset # unstage всё
git commit --amend --no-edit --allow-empty
Отличие от других способов исправить код #
# git commit --amend
# Когда: последний коммит, не запушен
# Результат: переписана история, хеш изменился
# Риск: высокий если запушили
# git revert
# Когда: нужно отменить коммит но сохранить историю
# Результат: создаётся новый коммит отменяющий изменения
# Риск: низкий, безопасно в public ветках
# git reset
# Когда: откатить несколько коммитов
# Результат: удаления коммитов из истории
# Риск: очень высокий, легко потерять работу
# git rebase -i
# Когда: переписать историю несколько коммитов
# Результат: полная переписка истории
# Риск: очень высокий для public веток
Заключение #
git commit --amend — быстрый способ исправить последний коммит без создания отдельного коммита. С --no-edit не открывает редактор. С -m "текст" меняет сообщение. С git add перед вызовом — добавляет файлы в коммит. После push требует --force-with-lease. Используйте только в личных ветках которые не запушили или запушили но никто на них не полагается. Для более ранних коммитов используйте git rebase -i. Подробнее об отмене коммитов и git reflog.