
Как работает git reset: разница между soft, mixed и hard

Что делает команда git reset
git reset перемещает указатель текущей ветки (HEAD) на другой коммит и тем самым отменяет изменения. Команда затрагивает три области репозитория:
- HEAD — текущий коммит ветки.
- Index (staging area) — индекс, то есть набор файлов, подготовленных к следующему коммиту.
- Working directory — файлы на диске.
Какие из этих областей изменятся, определяет режим: --soft, --mixed или --hard.
Три дерева Git
Понимание git reset строится на модели трёх деревьев:
| Дерево | Что хранит |
| HEAD | Снимок последнего коммита текущей ветки |
| Index (staging area) | Снимок следующего коммита — то, что попадёт в *git commit* |
| Working directory | Файлы, с которыми вы работаете на диске |
Эта модель описывает не только git reset, но и git checkout, и git add.
Режимы git reset
git reset --soft
--soft перемещает только HEAD на указанный коммит. Индекс и рабочая директория остаются без изменений: всё, что было в отменённых коммитах, сохраняется в staging area как готовое к новому коммиту.
Когда полезно: объединить несколько коммитов в один (squash), не теряя проиндексированных изменений.
git reset --mixed (по умолчанию)
--mixed перемещает HEAD и обновляет индекс, но не трогает файлы на диске. Изменения остаются в рабочей директории, однако становятся непроиндексированными (unstaged).
Это режим по умолчанию: git reset HEAD~1 без флага работает именно так.
Когда полезно: отменить git add и собрать коммит заново из других файлов.
git reset --hard
--hard — единственный режим, который меняет файлы на диске. Он перемещает HEAD, обновляет индекс и перезаписывает рабочую директорию содержимым указанного коммита. Все незакоммиченные изменения при этом теряются безвозвратно.
Перед запуском убедитесь, что незакоммиченные правки вам не нужны.
Сравнительная таблица режимов
| Режим | HEAD | Index | Working directory |
| *--soft* | перемещается | не меняется | не меняется |
| *--mixed* | перемещается | сбрасывается | не меняется |
| *--hard* | перемещается | сбрасывается | перезаписывается |
git reset, git revert и git checkout: в чём разница
git reset перемещает указатель ветки и переписывает историю, поэтому не подходит для коммитов, которые уже запушены в общий репозиторий. Документация Git прямо предупреждает: git reset --hard не следует применять к коммитам, видимым другим участникам.
git revert решает ту же задачу безопаснее: он создаёт новый коммит, который отменяет изменения предыдущего, и не переписывает историю. Подходит для общих веток.
git checkout (и современный аналог git switch) переключает HEAD на другой коммит или ветку, но не двигает указатель текущей ветки. В этом его принципиальное отличие от git reset.
Практические сценарии
Отменить последний коммит, сохранив изменения в staging:
git reset --soft HEAD~1
Разбить коммит на несколько, выбрав файлы заново:
git reset HEAD~1 # эквивалентно git reset --mixed HEAD~1
Откатить локальную ветку к состоянию удалённой:
git reset --hard origin/main
Заключение
git reset --hard необратимо удаляет незакоммиченные изменения из рабочей директории. Перед выполнением проверьте, что они вам не нужны.
Оставьте заявку, чтобы получить консультацию
Наши специалисты свяжутся с вами в ближайшее время и ответят на все вопросы.

Узнавайте о выходе новых статей в блоге первыми!
Будем держать в курсе новостей и облачных трендов


Почитать по теме


Перенос дисков PV в Managed Kubernetes от VK Cloud: данные переживают кластер

