Ответ
Есть несколько способов отката изменений в Git, в зависимости от того, на каком этапе находится файл.
1. Откат незакоммиченных изменений в рабочей директории
Если вы еще не добавили файл в индекс (git add), чтобы отменить все локальные правки и вернуть файл к состоянию последнего коммита:
git restore <file>
# Или устаревшая, но знакомая команда:
# git checkout -- <file>
2. Откат изменений, добавленных в индекс (staged)
Если вы выполнили git add, но еще не закоммитили:
# Убираем файл из индекса, но сохраняем изменения в рабочей директории
git restore --staged <file>
# Затем, если нужно, откатываем и сами изменения в файле:
git restore <file>
3. Создание коммита, отменяющего предыдущий (revert)
Безопасный способ отменить изменения, уже попавшие в историю. Создает новый коммит с инверсными изменениями.
# Откатываем конкретный коммит
git revert <commit-hash>
# Откатываем последний коммит
git revert HEAD
4. «Удаление» коммита из истории (reset)
Опасно! Меняет историю. Используйте только в локальной ветке, если изменения не были отправлены в общий репозиторий.
# «Удаляет» последний коммит, но оставляет изменения в рабочей директории
git reset --soft HEAD~
# «Удаляет» последний коммит и убирает изменения из индекса
git reset HEAD~
# «Удаляет» последний коммит и полностью стирает изменения из файлов
git reset --hard HEAD~
5. Поиск и восстановление утерянных коммитов
Если вы уже сделали reset --hard и потеряли коммит, его можно найти и восстановить:
# Показать историю всех действий (включая «удаленные» коммиты)
git reflog
# Восстановить состояние на момент выбранного действия
git reset --hard <hash-from-reflog> Ответ 18+ 🔞
А, ну вот, опять накосячил с кодом и надо всё откатить? Бывает, чёрт возьми, со всеми случается. Сейчас разберёмся, как из этой жопы вылезти. Главное — не паниковать и не делать резких движений, а то можно так наворотить, что потом неделю откатываться.
Смотри, тут всё зависит от того, на каком этапе ты обосрался. Как будто слоёный пирог из ошибок, только невкусный.
Первый вариант — самый простой. Ты просто в файле что-то натыкал, но ещё даже не добавил это в индекс командой git add. То есть, по сути, ты ещё даже не начал серьёзно косячить. Чтобы всё стереть и вернуться к тому, что было в последнем коммите, делай так:
git restore <file>
# Или, если ты из старых, и эта команда у тебя в подкорке:
# git checkout -- <file>
Всё, и волнение ебать как рукой сняло. Файл станет чистым, как будто ты нихуя и не трогал.
Второй вариант — ты уже успел сделать git add. Вот тут уже интереснее. Ты как бы приготовил свои косяки к отправке, но ещё не отправил. Чтобы их оттуда выковырять:
# Сначала вытаскиваем файл из этого стейджа, но сами правки пока остаются в файле
git restore --staged <file>
# А если ты передумал и хочешь отменить вообще всё — дохуячим вторую команду:
git restore <file>
Понимаешь разницу? Сначала мы говорим «не, это говно не для коммита», а потом, если надо, зачищаем и сами правки.
Третий способ — для уже закоммиченного говна. Вот это уже серьёзно. Твои косяки попали в историю. Самый безопасный и правильный путь — не пытаться их вычеркнуть, а сделать новый коммит, который всё отменит. Это как сказать: «Извините, все, я был не прав, давайте вернём как было».
# Откатываем конкретный коммит по его хешу
git revert <commit-hash>
# Или, если надо откатить самый последний твой «подвиг»
git revert HEAD
Git создаст новый коммит с обратными изменениями. История останется целой, все будут видеть, что ты накосячил, но потом исправился. Честно и прозрачно, доверия ебать ноль, но зато безопасно для команды.
Четвёртый способ — для отчаянных. Это git reset. Ёпта, вот тут надо быть осторожным, как сапёр. Эта команда не создаёт новый коммит, а стирает историю. Если ты уже запушил свои изменения в общий репозиторий, и потом сделаешь reset — будет вам хиросима и нигерсраки, когда ты попробуешь запушить снова. Используй ТОЛЬКО если косяк локальный и ты его никуда не отправлял.
# «Удаляем» последний коммит, но все твои правки остаются в рабочей папке (как будто после git add)
git reset --soft HEAD~
# «Удаляем» коммит и убираем изменения из индекса (как будто до git add)
git reset HEAD~
# «Удаляем» коммит и ВООБЩЕ ВСЁ СТИРАЕМ. Безвозвратно. Нахуй.
git reset --hard HEAD~
Последний вариант, --hard, — это точка невозврата. После него изменения сгорят. Ты уверен? Ну, типа, совсем уверен? Ладно, твоё дело.
И, наконец, пятый — спасательный круг. Допустим, ты уже сделал reset --hard и охренел: «Бля, а там же была нужная фича!». Всё пропало? Не совсем. Git — хитрая жопа, он почти всё помнит какое-то время.
# Эта команда покажет тебе ЛОГ ВСЕХ ТВОИХ ДЕЙСТВИЙ. Где ты был, что делал, куда совался.
git reflog
# Найдёшь в этом списке хеш того состояния, до которого хочешь откатиться, и — бац!
git reset --hard <hash-from-reflog>
Это как машина времени. Главное — успеть, пока мусор не вычистили.
Вот и вся магия. Главное — понимать, на каком ты этапе, и не использовать тяжёлую артиллерию там, где можно просто аккуратно всё отменить. Удачи, не накосячь ещё больше!