Сброс состояния ветки
Иногда хочется отменить целую серию коммитов и вернуть ветку в прошлое.
Представь ситуацию: я экспериментирую с новыми возможностями в отдельной ветке, но после пары коммитов понимаю, что идея провальная. Я хочу выбросить все эти экспериментальные коммиты и начать заново с того места, где ветка отделилась от main.
Здесь на помощь приходит команда . Чтобы воспроизвести эту ситуацию, давай сначала создадим ветку experiment.
git switch -c experimentСоздай ветку experiment и переключись на неё.
Отлично! Теперь создай файл experiment.html. Впиши в него строку This is an experiment., подготовь и закоммить изменения.
Выполни все действия из текста выше.
Супер! Теперь удали строку <!DOCTYPE html> из файла hello.html, подготовь и закоммить.
Выполни все действия из текста выше.
Итак, допустим, на этом этапе я протрезвел осознал, что эксперимент зашёл в тупик. Я хочу сбросить ветку experiment до изначального состояния и избавиться от всех экспериментальных коммитов.
Для этого можно использовать команду git reset, добавив к ней ссылку на коммит, к которому мы хотим откатиться. В нашем случае это тот самый коммит, от которого изначально ответвилась experiment. То есть последний коммит в ветке main. А значит, вместо хеша коммита можно просто указать имя ветки, на которую мы ориентируемся: main.
git reset mainСбрось ветку experiment к последнему коммиту из main.
Если сейчас проверить статус репозитория, мы увидим, что файл experiment.html всё ещё на месте, но Git считает его untracked. То есть он не подготовлен и не закоммичен.
Если заглянуть в hello.html, то строки <!DOCTYPE html> там по-прежнему нет. Выходит, рабочее дерево не изменилось. В нём всё так же лежат наши экспериментальные правки.
Git передвинул указатель ветки на тот же коммит, что и main. Коммиты, которые мы сделали в ветке experiment, больше не входят в её историю. Это называется смешанным сбросом (mixed reset) — коммиты удалились, изменения остались в рабочем дереве, но пропали из области подготовки.
Если мы хотим сохранить эти правки, их можно заново подготовить и закоммитить, как обычно. Иногда именно это и нужно. Например, чтобы объединить несколько мелких коммитов в один осмысленный или наоборот — разбить гигантский коммит на несколько маленьких.
Но в нашей ситуации задача другая — окончательно избавиться от экспериментального кода. А значит, нужен жёсткий сброс (hard reset).
Вообще-то, мы можем отменить все изменения в рабочем дереве прямо сейчас! Воспользуйся командой, которую мы изучали чуть раньше (подсказка: это git restore). Если не помнишь, как она работает, загляни в .
Отмени изменения в рабочем дереве.
Отлично! На самом деле, жёсткий сброс можно было сделать одной командой, добавив флаг --hard к git reset. Запуск git reset --hard не раз выручал меня в прошлом.
Давай проверим статус репозитория.
git statusПроверь статус репозитория.
Правки в hello.html пропали. Но файл experiment.html всё ещё на месте! Почему так?
Так как файл неотслеживаемый, Git о нём ничего не знает. Такой файл не входит в репозиторий, поэтому команда сброса на него никак не влияет. Чтобы полностью избавиться от файла, его нужно просто удалить с помощью команды .
rm experiment.htmlУдали файл experiment.html.
Давай проверим статус репозитория.
git statusПроверь статус репозитория.
Супер! Наша ветка вернулась в то состояние, в котором мы её создавали.
Прежде чем идти дальше, переключись на ветку main.
Если хочется сохранить изменения из отброшенных коммитов, используй git reset --soft вместо обычного git reset. Это сместит указатель ветки, но оставит все правки из отменённых коммитов в области подготовки.
А если нужно стереть любые следы отброшенных коммитов, выполняй git reset --hard. Это переместит указатель ветки и уничтожит все изменения как в рабочем дереве, так и в области подготовки. Использовать с осторожностью!
С командой git reset нужна осторожность, особенно с флагом --hard, так как она может навсегда удалить изменения. Всегда проверяй, к тому ли коммиту ты откатываешься. Если незакоммиченные правки ещё могут пригодиться, перед сбросом спрячь их через git stash.
Команда git reset чем-то похожа на git restore, по крайней мере, по названию. Обе можно использовать для отмены изменений в рабочем дереве. Однако git restore новее и делает меньше вещей: она умеет только восстанавливать файлы в рабочем дереве, но не двигает указатель ветки. Собственно, ради этого её и придумали: чтобы отдельно сдвигать указатель ветки и отдельно восстанавливать файлы. При использовании git restore сложнее случайно что-то сломать, так как команда более предсказуемая и менее разрушительная, чем git reset.
Конечно, тем, у кого уже есть привычка к старому доброму git reset, может потребоваться время, чтобы переучиться. Но если ты только начинаешь изучать Git, лучше сразу понять разницу и стараться использовать git restore, когда это уместно.
Пройди курс так, как задумано: порционное обучение, чёткий порядок и постепенное открытие статей в Gitопедии. В любой момент можно продолжить работу с настоящим Git прямо в VS Code, Cursor, Antigravity или Windsurf.
(требуется войти в аккаунт)