↓Перейти к содержанию
  1. Git: руководства и команды/

git commit --amend: изменение последнего коммита

·8 минут·

Вы только что сделали коммит и заметили опечатку в сообщении. Или забыли добавить один файл. 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 если:

  1. Коммит уже в удалённом репозитории и его видели другие разработчики
  2. Коммит в main или develop ветке
  3. Коммит слит (merged) в другую ветку
  4. Вы работаете в команде и коммит может быть основой для их работы

Почему опасно:

  • 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.