Что такое 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) — это впечатляет.