> Как откатывать изменения в Git

Уровень: senior · Категория: Технические вопросы

Компании: Aston

> Пример ответа

Короткий ответ

Откат изменений в Git зависит от того, где находятся изменения: в рабочей директории, в индексе (staging area) или в истории коммитов. Для рабочей директории используется git restore или git checkout --, для индекса - git restore --staged, для последнего коммита - git reset или git revert. Ключевое различие: reset переписывает историю, revert создаёт новый коммит, отменяющий изменения. Выбор зависит от того, опубликованы ли коммиты в удалённом репозитории.

Подробное объяснение

Откат изменений - это не одна команда, а набор инструментов, каждый из которых решает конкретную задачу. Основные сценарии:

  1. Изменения в рабочей директории (не закоммичены, не в индексе): git restore <file> или git checkout -- <file>. Это вернёт файл к состоянию последнего коммита.

  2. Изменения в индексе (staged, но не закоммичены): git restore --staged <file> убирает файл из индекса, но сохраняет изменения в рабочей директории. Если нужно полностью откатить и индекс, и рабочую директорию: git restore --staged --worktree <file>.

  3. Последний коммит (не опубликован): git reset --soft HEAD~1 (коммит отменяется, изменения остаются в индексе), git reset --mixed HEAD~1 (изменения в рабочей директории), git reset --hard HEAD~1 (все изменения удаляются полностью).

  4. Опубликованные коммиты: git revert <commit-hash> создаёт новый коммит, который отменяет изменения указанного коммита. Это безопасно для совместной работы, так как не переписывает историю.

  5. Откат к конкретному коммиту в истории: git reset --hard <commit-hash> - переписывает историю, опасно для опубликованных веток. git revert - безопасная альтернатива.

Важно понимать trade-off: reset меняет историю, что может вызвать конфликты у других разработчиков, revert сохраняет историю, но создаёт дополнительные коммиты.

На практике

Для senior-уровня важно не только знать команды, но и понимать контекст. На практике:

  • Если изменения не были запушены - можно использовать reset с любым режимом.
  • Если изменения уже в удалённом репозитории - только revert, чтобы не сломать историю для коллег.
  • Для отката одного файла из опубликованного коммита: git revert <commit> затем git reset --soft HEAD~1 и git restore --staged <file> - но это сложный путь, обычно проще сделать новый коммит с исправлением.
  • git reflog - мощный инструмент для восстановления после ошибочного reset --hard. Он показывает все перемещения HEAD, и через него можно вернуться к любому состоянию.

Пример кода

BASH
# Откат незакоммиченных изменений в одном файле
git restore src/main.js
# Убрать файл из индекса, сохранив изменения
git restore --staged src/main.js
# Отменить последний коммит, сохранив изменения в рабочей директории
git reset --soft HEAD~1
# Полностью удалить последний коммит и все изменения
git reset --hard HEAD~1
# Безопасная отмена опубликованного коммита
git revert abc1234
# Восстановление после ошибочного reset --hard
git reflog
git reset --hard HEAD@{2}

Как отвечать на собеседовании

Начните с классификации: рабочая директория, индекс, история. Затем для каждого случая назовите команду и объясните, почему именно она. Обязательно упомяните разницу между reset и revert, подчеркнув, что revert - единственный безопасный способ для опубликованных коммитов. Хорошо добавить пример из практики: как вы откатывали изменения в реальном проекте и какие последствия учитывали. Если спросят про --hard - объясните, что это необратимо без reflog, и что reflog - ваш страховочный инструмент.

Что проверяет интервьюер

Интервьюер оценивает:

  • Понимание трёх уровней хранения изменений (working tree, index, history).
  • Умение выбирать инструмент под конкретный сценарий.
  • Осознание последствий переписывания истории в командной работе.
  • Знание reflog как механизма восстановления.
  • Способность объяснить trade-off между reset и revert.

Типичные ошибки

  • Использование git reset --hard для опубликованных коммитов - это ломает историю для всех.
  • Путаница между git restore и git reset: restore работает с файлами, reset - с коммитами и индексом.
  • Забывают про --staged при работе с индексом, из-за чего откатывают не то, что нужно.
  • Уверенность, что git revert удаляет коммит - на самом деле он создаёт новый, обратный.
  • Игнорирование git reflog как способа восстановления после ошибочных операций.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью