Перейти к содержанию
Innovialabs

Как отменить изменения в Git: reset, revert и restore

Практика3 мин

Коротко

restore отменяет правки в файлах, reset двигает ветку назад в локальной истории, revert создает новый коммит-отмену для уже опубликованного кода, а reflog помогает вернуть «потерянное».

Короткий ответ

Выбор команды зависит от двух вопросов: что вы хотите отменить и опубликованы ли уже изменения.

СитуацияКоманда
Испортил файл, еще не делал git addgit restore <файл>
Добавил лишнее в индексgit restore --staged <файл>
Последний коммит неудачный, не запушенgit reset --soft HEAD~1
Нужно исправить сообщение последнего коммитаgit commit --amend
Баг уже в общей веткеgit revert <хеш>
Удалил ветку или сделал reset --hard по ошибкеgit reflog + git branch / git reset

Главное правило: не переписывайте историю, которую уже забрали другие. Для опубликованных коммитов используйте revert.

restore: отмена правок в файлах

git restore работает с файлами, а не с коммитами.

git restore src/app.js           # вернуть файл к последнему коммиту
git restore --staged src/app.js  # убрать из индекса, правки остаются
git restore --source=HEAD~2 src/app.js  # взять версию двухкоммитной давности

Осторожно: git restore <файл> без --staged безвозвратно удаляет незакоммиченные правки в этом файле. Git их не сохранял — reflog не поможет.

reset: перенос ветки назад

git reset перемещает указатель текущей ветки на другой коммит. Три режима отличаются тем, что происходит с изменениями из «отброшенных» коммитов:

РежимВеткаИндекс (staged)Рабочие файлы
--softсдвигаетсяизменения остаются в индексене трогаются
--mixed (по умолчанию)сдвигаетсяочищаетсяизменения остаются в файлах
--hardсдвигаетсяочищаетсяперезаписываются

Практика:

  • git reset --soft HEAD~1 — «разкоммитить», чтобы переделать коммит или объединить несколько в один.
  • git reset HEAD~1 — то же, но изменения нужно заново добавить через git add; удобно, чтобы разбить коммит на несколько.
  • git reset --hard origin/main — выбросить все локальные изменения и привести ветку к удаленной. Незакоммиченная работа пропадет.

Если ветка уже запушена, после reset придется делать git push --force-with-lease. В личной ветке это допустимо, в main — почти никогда.

revert: безопасная отмена опубликованного

git revert не удаляет коммит, а создает новый коммит с обратными изменениями. История сохраняется, коллегам ничего не нужно чинить.

git revert a1b2c3d          # отменить один коммит
git revert HEAD~3..HEAD     # отменить диапазон из трех последних
git revert -m 1 <merge-хеш> # отменить merge-коммит

Для merge-коммита -m 1 указывает, какой родитель считать основным (обычно первый — ветка, в которую сливали). Учтите: если позже снова слить ту же ветку, Git посчитает, что ее изменения уже применялись, и придется «отменить отмену».

reflog: спасательный круг

Git записывает каждое перемещение HEAD в reflog. Это локальный журнал, и он спасает почти любую ошибку с коммитами.

git reflog
# 9f8e7d6 HEAD@{0}: reset: moving to HEAD~3
# 4c5d6e7 HEAD@{1}: commit: add payment form
# ...

git reset --hard 4c5d6e7        # вернуть ветку в прежнее состояние
git branch recovered 4c5d6e7    # или восстановить удаленную ветку

Ограничения: reflog хранится только у вас локально, записи со временем удаляются сборщиком мусора, и он не содержит того, что никогда не было закоммичено.

Частые ошибки

  • reset --hard при незакоммиченной работе. Перед рискованной операцией сделайте git stash или временный коммит.
  • Force push в общую ветку. Ломает историю коллегам. Используйте revert.
  • Путаница между revert и reset. Revert добавляет коммит, reset двигает ветку.
  • Паника. Если что-то закоммичено хотя бы раз, оно почти наверняка восстанавливается через reflog.

Частые вопросы

git checkout исторически делал и переключение веток, и восстановление файлов. Начиная с Git 2.23 эти роли разделили между git switch и git restore, чтобы команды было сложнее перепутать. Старый вариант по-прежнему работает.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.