git restore: отмена изменений в рабочей директории
Что такое git restore #
Команда git restore — это относительно молодая команда в мире Git, которая появилась в версии Git 2.23 в августе 2019 года. Её создали для того, чтобы разделить огромное количество функций команды git checkout на несколько специализированных команд.
Основная задача git restore — помочь разработчикам работать с изменениями в двух ключевых местах:
- Рабочая директория (working tree) — файлы, которые вы видите и редактируете
- Staging area (индекс) — файлы, подготовленные к коммиту (добавленные через
git add)
Раньше для этих операций приходилось использовать git checkout или git reset, что было запутанно, потому что эти команды делали слишком много разных вещей одновременно. git restore решает проблему простотой и ясностью: её название точно описывает, что она делает — восстанавливает файлы.
Восстановление файла в рабочей директории #
Самый распространённый сценарий: вы отредактировали файл, но потом решили отменить все изменения и вернуть файл к его состоянию в последнем коммите.
Отмена изменений в одном файле #
git restore file.txt
Эта команда полностью отменяет все изменения в файле file.txt, которые не были закоммичены. Файл вернётся к точно такому же состоянию, в котором он находился в HEAD (последнем коммите текущей ветки).
Отмена изменений во всех файлах #
git restore .
Точка (.) означает «все файлы в текущей директории и её подпапках». Эта команда восстановит все файлы в проекте.
Отмена изменений по паттерну #
git restore *.js
git restore src/
git restore src/components/*.tsx
Вы можете использовать wildcards (подстановочные знаки) и пути к папкам для более тонкого контроля. Например, команда выше восстановит все JavaScript-файлы в текущей директории, всю папку src/, или только файлы TypeScript React компонентов.
Важное предупреждение #
Внимание: изменения, которые вы отменяете через git restore, теряются безвозвратно. Git не сохраняет их нигде. Поэтому перед выполнением убедитесь, что вам действительно не нужны эти изменения.
Если вы вдруг передумали и хотите сначала посмотреть, что именно изменилось, используйте:
git diff file.txt
Убрать файл из staging area (отмена git add) #
Другая частая ситуация: вы добавили файл в staging area через git add, но потом передумали его коммитить. Нужно его оттуда убрать.
Убрать файл из индекса #
git restore --staged file.txt
Флаг --staged (также известный как --cached) говорит Git’у работать не с рабочей директорией, а с индексом (staging area). После этой команды файл останется в вашей рабочей директории со всеми его изменениями, но из коммита он не попадёт.
Убрать из staging area все файлы #
git restore --staged .
Различие между –staged и –worktree #
Важно понимать разницу между двумя основными флагами git restore:
--worktree(или вообще без флага) — работает с файлами в рабочей директории. Изменения в файлах отменяются.--staged— работает с индексом. Файлы убираются из staging area, но остаются изменёнными в рабочей директории.
Эта разница критична. Если вы забудете флаг --staged и просто напишете git restore file.txt, изменения будут полностью отменены как в рабочей директории, так и удалены из staging area.
Комбо: убрать из staged И отменить изменения #
Иногда нужно сделать сразу обе операции: убрать файл из staging area И отменить его изменения в рабочей директории.
git restore --staged --worktree file.txt
Или короче:
git restore -S -W file.txt
Где -S — это краткая форма для --staged, а -W — для --worktree.
После такой команды файл вернётся к своему исходному состоянию полностью — и в рабочей директории, и в индексе.
Восстановить файл из конкретного коммита или ветки #
Более продвинутый сценарий: вам нужно восстановить файл не из текущего коммита (HEAD), а из какого-то другого.
Восстановить из коммита с относительной позицией #
git restore --source HEAD~2 file.txt
HEAD~2 означает «два коммита назад от текущей позиции». После этой команды файл будет восстановлен в том виде, в котором он был два коммита назад.
Вы можете использовать любое количество тильд:
HEAD~1— предыдущий коммитHEAD~3— три коммита назадHEAD~10— десять коммитов назад
Восстановить из другой ветки #
git restore --source feature-branch config.json
Это полезно, если вам нужна версия файла из другой ветки разработки.
Восстановить из тега (релиза) #
git restore --source v1.0.0 package.json
Например, если вам нужна версия файла из какого-то релиза вашего проекта.
Восстановить из конкретного коммита по хешу #
git restore --source abc1234 src/app.js
Если вы знаете точный хеш коммита, можете использовать его.
Таблица сравнения: git restore vs git checkout vs git reset #
Разновидность команд Git для работы с изменениями может быть запутанной. Вот сравнительная таблица:
| Команда | Что делает | Изменяет историю? | Когда использовать |
|---|---|---|---|
git restore file.txt | Отменяет изменения в файле в рабочей директории | Нет | Когда вы хотите отменить свои правки в файле |
git restore --staged file.txt | Убирает файл из staging area (индекса) | Нет | Когда вы добавили файл через git add, но не хотите его коммитить |
git restore --staged --worktree file.txt | Полностью откатывает файл к последнему коммиту | Нет | Когда нужна полная отмена всех изменений файла |
git checkout -- file.txt | То же самое, что git restore file.txt | Нет | Старый способ, есть в старых версиях Git |
git reset HEAD file.txt | То же самое, что git restore --staged file.txt | Нет | Старый способ, есть в старых версиях Git |
git reset --hard HEAD | Откатывает все коммиты и удаляет изменения | Да (удаляет коммиты!) | Когда вам нужно удалить несколько последних коммитов |
git reset HEAD~1 | Откатывает последний коммит, но сохраняет изменения в рабочей директории | Да (удаляет коммит!) | Когда вы случайно закоммитили что-то, что не нужно |
Ключевое отличие: git restore никогда не изменяет историю коммитов. Это чистая команда для работы с текущим состоянием файлов. git reset может удалять коммиты из истории, что опаснее.
Подробнее об отличиях между этими командами читайте в статьях про /ru/git/git-reset/ и /ru/git/otmenit-izmeneniya-fajl-git/.
Типичные ошибки и их решения #
Ошибка: pathspec ‘file.txt’ did not match any files #
error: pathspec 'file.txt' did not match any file(s) known to git
Это означает, что Git не нашёл файл с таким названием. Возможные причины:
- Неправильное имя файла — проверьте, правильно ли написано имя
- Файл не отслеживается Git’ом — убедитесь, что файл хотя бы раз был закоммичен
- Вы находитесь в неправильной директории — перейдите в корень репозитория через
cdили укажите полный путь
git restore ./path/to/file.txt
Ошибка: Refusing to remove … file #
Refusing to remove ... file to force restoration
Это происходит, когда в файле есть изменения, которые отличаются от версии в индексе. Git осторожничает и не хочет потерять данные. Используйте флаг --force:
git restore --force file.txt
Ошибка: option ‘–staged’ and ‘–worktree’ cannot be used together #
На самом деле, это не ошибка. Флаги --staged и --worktree можно использовать вместе для выполнения обеих операций одновременно. Если вы получили такую ошибку, это может быть проблема с версией Git. Обновите Git на более новую версию.
Часто задаваемые вопросы (FAQ) #
Что делает команда git restore? #
git restore восстанавливает файлы в их исходное состояние. Она может работать двумя способами: отменять изменения в рабочей директории или убирать файлы из staging area. Команда появилась в Git 2.23 как замена части функций git checkout и git reset, чтобы сделать работу с файлами более интуитивной и безопасной.
Чем git restore отличается от git reset? #
Главное отличие: git restore работает только с файлами и не трогает историю коммитов, а git reset может удалять коммиты из истории. git restore безопаснее для обычных задач. Используйте git restore для отмены изменений в файлах, а git reset только если вам действительно нужно удалить коммиты.
Подробнее в статье про /ru/git/git-reset/.
Как отменить все незакоммиченные изменения git? #
git restore .
Эта команда отменит все изменения во всех файлах текущей директории и поддиректориях. Используйте с осторожностью — изменения будут потеряны безвозвратно.
Как убрать файл из git add (unstage)? #
git restore --staged file.txt
Флаг --staged убирает файл из staging area (индекса), но оставляет его изменения в рабочей директории. После этой команды файл останется в вашем проекте с изменениями, но в следующий коммит не попадёт.
Если нужна была убрать файл из staging area, смотрите также /ru/git/git-add/.
Можно ли восстановить файл после git restore? #
К сожалению, нет. Изменения, удалённые через git restore, теряются безвозвратно. Git их не сохраняет. Поэтому всегда дважды проверяйте, что вы хотите это делать, или используйте git diff для просмотра изменений перед их отменой.
Однако если вы случайно удалили файл полностью (а не только изменил его), но файл был закоммичен раньше, вы можете его восстановить через git restore --source HEAD~N, указав нужный коммит.
В чём разница git restore и git checkout? #
git checkout — старая команда, которая делает слишком много разных вещей. git restore — новая команда, специально для работы с файлами. Для большинства случаев git restore является лучшим выбором.
Старый способ: git checkout -- file.txt
Новый способ: git restore file.txt
Оба делают одно и то же, но новый способ более понятный и читаемый.
Практические примеры использования #
Пример 1: Отмена случайных изменений #
Вы редактировали файл src/main.js, но потом понял, что всё испортил. Чтобы быстро вернуть его:
git restore src/main.js
Пример 2: Отмена git add перед коммитом #
git add config/secrets.json # Ой, не нужно было добавлять!
git restore --staged config/secrets.json
Теперь файл остаётся в рабочей директории с изменениями, но в коммит не попадёт.
Пример 3: Отмена всех изменений перед слиянием веток #
Перед тем как выполнить git merge, вы хотите убедиться, что у вас нет неза́кодиченных изменений:
git restore .
Пример 4: Восстановить файл из предыдущей версии #
Вы хотите посмотреть, как выглядел файл package.json в последнем стабильном релизе:
git restore --source v2.0.0 package.json
Теперь файл будет в том состоянии, в котором он был в версии 2.0.0.
Наиболее частые сценарии в реальной работе #
Сценарий 1: Вы внесли изменения, добавили их через git add, но потом поняли, что вам нужно что-то переделать.
git restore --staged . # Уберём из staging area
git restore . # Отменим изменения
# Теперь всё как было в последнем коммите
Сценарий 2: Вы работали над двумя файлами, но закоммитить хотите только один.
git add file1.js file2.js
git restore --staged file2.js # Убрали file2.js из коммита
git commit -m "Update file1" # Коммитим только file1
Сценарий 3: Нужно откатить изменения в конкретной папке, но оставить остальное.
git restore src/old-code/
Заключение #
Команда git restore — это простой и мощный инструмент для работы с файлами в Git. Она делает две основные вещи:
- Отменяет изменения в рабочей директории —
git restore file.txt - Убирает файлы из staging area —
git restore --staged file.txt
Благодаря своей специализированности и понятному названию, git restore лучше, чем старые команды git checkout и git reset, для большинства повседневных задач. Используйте её смело, но помните, что отменённые изменения потеряются безвозвратно.
Для более сложных сценариев работы с историей коммитов смотрите статью про /ru/git/pereyti-na-commit-git/.