git reset
git reset: сбросить HEAD и текущую ветку на другой коммит.
Команда git reset используется в основном для перемещения указателя HEAD и текущей ветки назад, на конкретный коммит. По сути, это позволяет «отмотать» историю проекта в прошлое. Она незаменима, когда нужно отменить коммиты, уже сделанные в текущей ветке.
С git reset Git словно забывает, что какие-то изменения вообще происходили, и считает текущим состоянием проекта один из прошлых этапов. Это суперполезно для отмены изменений, упрощения сложной истории или даже для объединения нескольких коммитов в один перед их отправкой в удалённый репозиторий.
Исторически git reset использовалась для самых разных задач, включая сброс рабочего дерева и области подготовки. И ветераны разработки до сих пор применяют git reset для этих целей. Но с появлением команды git restore в версии Git 2.23.0 для управления рабочим деревом и областью подготовки рекомендуется использовать именно её, а git reset оставить для перемещения HEAD и указателя текущей ветки.
Используя git restore, сломать что-то гораздо сложнее, так как она более точечная и менее разрушительная по сравнению с git reset. Тем, кто привык к старой команде git reset, может потребоваться время, чтобы переучиться. Но если ты только знакомишься с Git, лучше сразу разобраться в разнице и стараться использовать git restore везде, где это уместно.
Примеры
Переместить текущую ветку на один коммит назад и сбросить область подготовки до состояния этого коммита, не меняя рабочую директорию. Правки из коммита, который перестал входить в историю ветки, окажутся вне области подготовки.
Частый сценарий — разбить поспешный коммит на несколько аккуратных или заново добавить в область подготовки только часть правок:
git reset HEAD~1Переместить текущую ветку на три коммита назад, не меняя область подготовки и рабочую директорию. Правки из этих коммитов окажутся вместе в области подготовки.
Частый сценарий — заменить несколько мелких или неаккуратных локальных коммитов одним чистым коммитом:
git reset --soft HEAD~3Переместить текущую ветку на два коммита назад и привести область подготовки и рабочую директорию к состоянию того коммита. Правки из этих двух коммитов, а также незакоммиченные правки в отслеживаемых файлах будут удалены. Незакоммиченные правки могут быть потеряны безвозвратно.
Частый сценарий — полностью отказаться от локального эксперимента, когда его коммиты или правки в отслеживаемых файлах точно не понадобятся:
git reset --hard HEAD~2В этих примерах HEAD~1 означает «один коммит перед HEAD». Число после ~ показывает Git, на сколько коммитов нужно вернуться: например, HEAD~3 означает «три коммита перед HEAD». Также можно указать хеш коммита, ветку или другую ссылку на коммит.
Будь осторожнее с git reset, особенно с флагом --hard, так как он может безвозвратно удалить изменения. Всегда перепроверяй, на правильный ли коммит делается сброс, и возьми за правило использовать git stash для сохранения незакоммиченных изменений перед сбросом, если есть подозрение, что они ещё могут пригодиться.
Обрати внимание, что git reset не удаляет коммиты целиком; команда лишь двигает указатель ветки. «Удалённые» коммиты по-прежнему остаются в истории репозитория (к ним можно обратиться по хешу), но они больше не связаны с текущей веткой. Это значит, что их можно восстановить при необходимости, просто они больше не будут отображаться в истории ветки.
.gitignoregit checkoutgit configgit taggit worktree