Gymterview
middle

Что такое git reset, git revert и git checkout? В чём разница?

git reset, git revert и git checkout — три команды для отмены изменений, работающие на разных уровнях: reset перемещает указатель ветки, revert создаёт коммит-отмену, checkout/restore восстанавливает файлы.

git reset

Перемещает указатель HEAD (и ветки) на другой коммит. Изменяет историю.

Пример
# --soft: перемещает HEAD, изменения остаются в staging area (index)
git reset --soft HEAD~1

# --mixed (по умолчанию): перемещает HEAD, сбрасывает index, рабочая директория не меняется
git reset --mixed HEAD~1
git reset HEAD~1          # то же самое

# --hard: перемещает HEAD, сбрасывает index и рабочую директорию
git reset --hard HEAD~1
# ОПАСНО: все незакоммиченные изменения ПОТЕРЯНЫ

# Сбросить конкретный файл из staging area
git reset HEAD src/Main.java
Режим HEAD Index (staging) Рабочая директория
--soft Перемещается Не меняется Не меняется
--mixed Перемещается Сбрасывается Не меняется
--hard Перемещается Сбрасывается Сбрасывается

git revert

Создаёт новый коммит, который отменяет изменения указанного коммита. Не изменяет историю — безопасен для shared-веток.

Пример
# Отменить последний коммит
git revert HEAD

# Отменить конкретный коммит
git revert a1b2c3d

# Отменить без автоматического коммита
git revert --no-commit a1b2c3d

# Отменить merge-коммит (нужно указать, какого родителя сохранить)
git revert -m 1 <merge-commit-hash>
Пример
До: C1 -- C2 -- C3
После git revert C2:
     C1 -- C2 -- C3 -- C2'  (C2' отменяет изменения C2)

git checkout / git restore (для файлов)

Восстанавливает файлы из указанного коммита или ветки. В новых версиях Git для этого рекомендуется git restore.

Пример
# Отменить изменения в файле (вернуть к последнему коммиту)
git checkout -- src/Main.java
# Современный аналог:
git restore src/Main.java

# Восстановить файл из конкретного коммита
git checkout a1b2c3d -- src/Main.java
# Современный аналог:
git restore --source=a1b2c3d src/Main.java

# Убрать файл из staging area
git restore --staged src/Main.java

Когда что использовать

Сценарий Команда Безопасно для shared?
Отменить локальный коммит, сохранив изменения git reset --soft HEAD~1 Нет
Полностью стереть последний коммит и изменения git reset --hard HEAD~1 Нет
Отменить коммит в shared/public ветке git revert <hash> Да
Откатить файл к состоянию из коммита git restore --source=<hash> file Да
Убрать файл из staging area git restore --staged file Да

Ключевые моменты

  • reset изменяет историю — безопасен только для локальных (не запушенных) коммитов
  • revert не изменяет историю — безопасен для shared-веток, создаёт новый коммит-отмену
  • reset --hard — деструктивная операция, незакоммиченные изменения будут потеряны безвозвратно
  • git restore (Git 2.23+) — рекомендуемая замена git checkout для операций с файлами

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

  • Использовать reset --hard на запушенных коммитах — другие разработчики потеряют синхронизацию
  • Путать reset и revert — reset переписывает историю, revert — нет
  • Забывать, что reset --hard уничтожает незакоммиченные изменения (используйте git stash перед этим)
  • Не знать про git reflog — позволяет восстановить потерянные коммиты после reset --hard

Как используется в 2026

  • git restore и git switch полностью заменили git checkout в ежедневной работе
  • IDE предоставляют удобный интерфейс для всех видов отмены (revert commit, rollback changes)
  • git reflog остаётся «страховочной сетью» — хранит историю перемещений HEAD в течение 90 дней
  • Защита веток (branch protection) не позволяет делать force push и тем самым предотвращает злоупотребление reset

На собеседовании: это вопрос-ловушка — многие путают три команды. Ключевое разделение: reset меняет историю (только для локальных коммитов), revert создаёт коммит-отмену (безопасен для shared), restore/checkout восстанавливает файлы. Нарисуйте таблицу режимов reset (–soft, --mixed, --hard) — это впечатляет.