Всем привет!

Если вы работаете с Git относительно недавно, почти наверняка у вас возникала потребность в отмене коммита. И, что печально, вы быстро поняли, что простого "откатить все назад" нет.

Где-то советуют git reset, где-то - git revert, а в третьих и вовсе пишется про checkout. По тому же правилу летят restore, amend, reflog и куча технологических формулировок, требующих знания git и после которых становится только сложнее, нежели понятнее.

На самом деле все это объясняется: под словами "отменить commit" можно иметь в виду совершенно разные действия:

  • Убрать последний commit;

  • Убрать commit, но оставить изменения в файлах;

  • Отменить commit, который уже отправили в удаленный репозиторий;

  • Вернуть один конкретный файл;

  • и т.д.

Именно это и вызывает необходимость в немалом количестве различных команд, которые вам и советуют в интернете.

В этой статье моя главная цель - разобрать все это нормально и по-человечески, без лишней каши из терминов, после которых новичок сразу закрывает статью. Прежде чем начать самую интересную для читателей, кликнувшим по заголовку, части, я хочу кратко разобрать малую часть терминологии.

Если это все вам не интересно и вы просто зашли скопипастить команду - можете смело листать вниз.

Итак, что мы разберем:

  1. Что такое коммит и что вообще значит "отменить commit" в Git;

  2. Когда нужно использовать какую команду;

  3. Как убрать последний commit без потери кода;

  4. Как безопасно отменить уже отправленный commit;

  5. Как вернуть только один файл;

  6. Приведем практические примеры, работая с git репозиторием Amvera (это облако для простого хостинга, где запуск кода и его обновление производится через push в привязанный git-репозиторий без настройки виртуальных машин).

Немного теории

Commit в Git - что это?

Простыми словами, коммит - это просто сохраненная точка проекта в определенный момент времени. Здесь возникает очень удобная аналогия с сохранениями в игре: в определенный момент появляется надобность в сохранении прогресса. Также и с Git: сохраняется текущий вариант файлов в репозитории.

Почему "откатить коммит" часто только путает

Как я уже говорил выше, под этой фразой можно подразумевать очень разные вещи. Иногда нужно убрать только коммит, но сохранить состояние кода. Когда-то нужно убрать и коммит, и код, а когда-то - вообще не трогать старый коммит, а только создать новый, который перекроет старый.

Поэтому в Git нет одной конкретной команды, зато есть множество команд, закрывающие каждую из потребностей.

Малая часть терминологии

Дальше, чтобы не путаться, достаточно знать несколько вещей:

  1. Локальный репозиторий - то есть проект, который лежит у вас на компьютере;

  2. Удаленный репозиторий - например репозиторий в GitHub, GitLab или в другом git-сервисе, куда вы отправляете коммиты через git push;

  3. Коммит - сохраненная точка проекта.

  4. Ветка - это линия развития проекта. Вы обычно работаете в основной ветке - main или master, но при желании можно создать другие. Например: dev для ветки с версиями кода, находящегося на разработке или prod для ветки с кодом, готового к публикации/запуска.

  5. HEAD - это указатель на текущий коммит, с которым вы сейчас работаете. Обычно он указывает на последний коммит текущей ветки.

Репозиторий - это папка, директория проекта, в которой Git хранит историю изменений.
git push - это команда, которая отправляет ваши коммиты (сохраненные точки проекта) в удаленный репозиторий.

С чего лучше начать запоминание

Если хочется максимально короткую версию без деталий, то:

  • git reset - когда нужно убрать последний commit локально (при этом изменения можно либо оставить, либо удалить). Здесь я все-таки рекомендую пролистать и прочитать про эту команду и ее использование, т.к. ей можно легко сломать историю;

  • git revert - когда нужно создать новый commit, который отменяет изменения старого commit (отменить commit, который уже отправлен);

  • git restore - когда нужно вернуть файл;

  • git commit --amend - когда нужно перекрыть старый коммит новым (исправить).

Теперь давайте разберем каждый случай отдельно.

Применения каждой из команд

1. Убрать последний commit локально - git reset

Если вы сделали commit, но поняли, что он лишний или ошибочный, можно убрать его с помощью git reset.

Есть несколько вариаций reset:

  1. --mixed (по умолчанию)

git reset HEAD~1

Здесь commit убирается из истории ветки, изменения остаются в файлах, но они удаляются из git add (git add нужно будет делать заново).

Что за "HEAD~1"? Тут все очень просто: ~1 значит "один коммит назад". Можно указать 2, 3, 4 и так далее.

  1. --soft

git reset --soft HEAD~1

Здесь похоже: commit удаляется из истории текущей ветки, изменения остаются, но файлы не удаляются из git add. Соответственно, добавлять их туда заново не нужно.

  1. --hard

git reset --hard HEAD~1

Это уже опасная команда: commit удаляется из истории вместе со всеми изменениями в файлах. То есть репозиторий полностью возвращается к состоянию предыдущего коммита.

Если вы случайно (бывает и такое) выполнили эту команду, но не хотели удалять коммит, то можно его восстановить с помощью команды git reflog, которую мы разберем чуть ниже.

2. Отменить commit, который уже был отправлен - git revert

Если commit уже был отправлен в удалённый репозиторий, использовать reset плохо - это может сломать историю у других разработчиков (если они есть)

В таком случае используют:

git revert <айди коммита>

Например:

git revert a1b2c3d

Тут git оставляет старый commit, но создает новый, который отменяет его изменения. То есть история фактически не переписывается.

Пример на буковках, где каждая буковка - айди коммита:

A - B - C - текущий коммит, где C - ошибочный коммит, который нужно перекрыть.

Если выполнить git revert C, получится:

A - B - C - D, где D - commit, который отменяет изменения C.

Это самый рекомендуемый и безопасный способ отмены изменений, если код уже был отправлен.

Практический пример git revert

Пример ниже показан на платформе Amvera - сервисе для легкого хостинга IT-приложений, где публикация проектов и их обновление происходят через push в git, но те же действия применимы к любому Git-репозиторию.

Предположим, что у нас есть простой проект, который автоматически деплоится после git push amvera master и вы уже подключили удаленный репозиторий.

Отправим коммит со "сломанным" кодом. Назовем его broken.py:

git add broken.py
git commit -m "Broken code"
git push amvera master

И тут мы понимаем - этот коммит нужно как можно быстрее отменить. Так как commit уже отправлен, самый безопасный вариант - это сделать revert.

git revert HEAD
git commit -m "Reverted commit"
git push amvera master

После этого как удаленный, так и локальный репозиторий изменятся:

Мы отменили коммит в Git и в репозитории от Amvera соответствующее уведомление
Мы отменили коммит в Git и в репозитории от Amvera соответствующее уведомление

3. Вернуть один файл - git restore

Иногда нужно отменить изменения не во всем коммите, а только в одном файле.

Например, вы что-то сломали в index.js. Тогда можно вернуть файл к состоянию последнего коммита:

git restore index.js

Git просто заменит файл на версию из последнего коммита.

Помимо возврата из последнего коммита, можно вернуть его из конкретного коммита:

git restore --source=<айди коммита> index.js

или

git restore --source=HEAD~1 index.js

4. Исправить последний commit - git commit --amend

Иногда commit уже сделан, но вы осознаете, что по каким-то причинам вы забыли добавить файл, написали плохой комментарий к коммиту или нужно слегка поправить код, то можно перезаписать последний commit.

Для этого используется комманда:

git commit --amend

Git откроет редактор, в котором можно изменить комментарий к коммиту. После изменений введите :wq или :qa и жмите Enter.

Если нужно добавить файлы в этот коммит, то сначала нужно:

git add файл

а потом:

git commit --amend

Git пересоберёт последний commit так, будто вы его сделали заново.

При этом я считаю важным подчеркнуть, что:

  • amend меняет историю

  • его желательно использовать только для таких коммитов, которые еще не отправлены

Практический пример для commit - git commit --amend

Как и в пункте 2, покажем на примере git репозитория облака для простого хостинга Amvera.

Когда ошибка небольшая, можно просто исправить коммит:

git add second.py
git commit --amend
git push amvera master --force # Осторожно с этим флагом!!! Он перезаписывает историю под текущий (новый) коммит

Выглядит это так (не учитывая действия прошлого способа):

Пример исправления коммита commit - git commit --amend
Пример исправления коммита commit - git commit --amend

5. Восстановление коммита после --hard - git reflog

Git ведёт журнал перемещений HEAD, что позволяет найти hash коммита и использовать его для восстановления.

Можно воспользоваться командой:
git reflog

Она покажет hash коммита в виде:

a1c2b3d (HEAD -> master) HEAD@{0}: commit (initial): Initial Commit

После того можно вернуть коммит:

git reset --hard a1c2b3d

6. Отмена git add - git restore --staged <имя файла>

Статья хоть и про коммиты, но я считаю, что про это тоже важно написать, хоть тут и писать нечего:

git restore --staged <имя файла>

Это отменит git add для конкретного файла.

Итог

Надеюсь, что статья была вам действительно полезна и вы узнали что-то новое. Если у вас остались вопросы или вы увидели в статье неточности - смело пишите в комментарии.

Комментарии (13)


  1. IgorPie
    15.03.2026 13:53

    простая, но очень хорошая статья, спасибо!


  1. WebMonet
    15.03.2026 13:53

    Чаще нужно удалить лишние файлы из коммитов (особенно запущенного в реп).


    1. MarkovM Автор
      15.03.2026 13:53

      Спасибо, возможно, напишу отдельную статью как удалять файлы из коммитов git и вносить в них изменения.


    1. savostin
      15.03.2026 13:53

      Ага, например секрет, который затруднительно поменять…


  1. mvv-rus
    15.03.2026 13:53

    Ну, статья, может, и хорошая - не могу судить, потому что я все эти команды давно уже вычитал в документации. Но почему ей поставлен уровень "сложная"? Новичков отпугивать? Или, наоборот, в качестве приза для самоооценки, типа "молодец, осилил сложную статью"?

    В статье же ничего сложного нет, никаких таких занудных подробностей git, как строен репозиторий и пр. Просто описано несколько полезных ритуалов - да-да, полезных, я же не просто так за ними в документацию лазил, а потому что по жизни понадобилось - но описано чисто на уровне как применять.


    1. JuriM
      15.03.2026 13:53

      Видимо статья написана для зумеров вайбкодеров, для них это сложно


    1. MarkovM Автор
      15.03.2026 13:53

      Уровень сложности очень субъевкивное понятие. Мне показалось, что примеры работы с командной строкой для откатов коммитов в Git не относятся к лёгкому материалу в сравнении со могими другими публикациями. А сложная или средняя уже сильно от читателя и его опыта зависит.


  1. art_konstanta
    15.03.2026 13:53

    Очень полезная и простая статья! Автору спасибо)


  1. danya_aleksandrov
    15.03.2026 13:53

    На самом деле мне иногда жаль, что stash не решает проблему того, что бы не приходилось коммитить что-то не нужное, в моей голове его применение выглядело бы более объемлемым


  1. mishast
    15.03.2026 13:53

    Хочу добавить.
    Если вы вдруг случайно закоммитили ключь в github -- все, меняйте. Даже переписывание последнего коммита не поможет (push force).
    Проводили тесты: роботы выхватывают api ключи в течении нескольких секкунд после коммита.


    1. kirillkosolapov
      15.03.2026 13:53

      Да, ключи лучше в переменных/секретах хранить. Чтобы они в коде даже при тестах не встречались. Сканирование на их наличие постоянно идет, иногда даже удивительно, почему GitHub с этим ничего не делает. А так, да, если улетел коммит с кредами в публичный Git, надо сразу креды сбрасывать и потом уже коммит в Git либо откатывать, либо новый, корректный пушить.


  1. amcured
    15.03.2026 13:53

    Катастрофически не хватает интерактивного git add -i, который для новичков не очевиден, и который помогает прямо от входа кардинально улучшить качество коммитов в смысле их атомарности.


  1. alextradex
    15.03.2026 13:53

    Вот такую бы картинку в статью
    Вот такую бы картинку в статью