Pull to refresh

3 режима команды git reset: --soft, --mixed(по умолчанию), --hard

Reading time 2 min
Views 279K
К моему удивлению на целом хабрахабре нет ни одного поста где бы было понятно написано про 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 да да да

Ну и напоследок картинкой: (thx to VBauer)

image
Tags:
Hubs:
+53
Comments 16
Comments Comments 16

Articles