К моему удивлению на целом хабрахабре нет ни одного поста где бы было понятно написано про 3 вида git reset
. Например, во второй по релевантности статье по запросу «git reset» автор пишет что «данное действие может быть двух видов: мягкого(soft reset) и жесткого(hard reset)». Режим --mixed
, используемый по умолчанию, почему-то не удостоился упоминания.
Ничего удивительного, что часто видишь непонимание работы этой команды. Под катом коротко и ясно расскажу о всех трёх режимах git reset
, после прочтения топика неясностей остаться не должно.
Сделанные изменения в репозитории по умолчанию имеют статус unstaged. Для того чтобы их закоммитить сначала вы должны добавить изменения в индекс, выполнив git add
. Когда вы делаете git commit
, в репозиторий будет закоммичено только то, что было в индексе.
git reset --soft
Возьмем для примера ветку:
- A - B - C (master)
HEAD указывает на C и индекс совпадает с C.
После выполнения
git reset --soft B
HEAD будет указывать на B и изменения из коммита C будут в индексе, как будто вы их добавили командой git add
. Если вы сейчас выполните git commit
вы получите коммит полностью идентичный C.
git reset --mixed (по умолчанию)
Режим --mixed
используется по умолчанию, т.е. git reset --mixed = git reset
Вернемся к тем же начальным условиям:
- A - B - C (master)
Выполнив
git reset --mixed B
или
git reset B
HEAD опять же будет указывать на B, но на этот раз изменения из С не будут в индексе и если вы запустите здесь git commit
ничего не произойдет т.к. ничего нет в индексе. У нас есть все изменения из С, но если запустить git status
то вы увидите, что все изменения not staged. Чтобы их закоммитить нужно сначала добавить их в индекс командой git add
и только после этого git commit
.
git reset --hard
Те же самые начальные условия:
- A - B - C (master)
Последний режим --hard
также как и --mixed
переместит HEAD на В и очистит индекс, но в отличие от --mixed
жесткий reset изменит файлы в вашей рабочей директории. Если выполнить
git reset --hard B
то изменения из С, равно как и незакоммиченные изменения, будут удалены и файлы в репозитории будут совпадать с B. Учитывая то, что этот режим подразумевает потерю изменений, вы всегда должны проверять git status
перед тем как выполнить жесткий reset чтобы убедиться что нет незакоммиченных изменений(или они не нужны).
Сравнительную таблицу режимов git reset
:
меняет индекс | меняет файлы в рабочей директории |
нужно быть внимательным |
|
---|---|---|---|
reset --soft |
нет | нет | нет |
reset [--mixed] |
да | нет | нет |
reset --hard |
да | да | да |
Автор: limonte