Урок курса

Правка больше не нужна: восстановить файл

Git и GitHub с нуля: бесплатный курс с практикой

В прошлом уроке git restore --staged снимала staged-изменение отслеживаемого файла, возвращая его запись в индексе к HEAD и сохраняя рабочий текст. git restore без этого флага перезаписывает рабочий файл версией текущего индекса и отбрасывает разницу с ней.

Источник git restore: индекс, а не HEAD напрямую

Когда вы выполняете git restore notes.txt без флага --staged, Git берёт версию файла из текущего индекса и перезаписывает ею файл в рабочей папке. Не из последнего коммита, не из HEAD напрямую — именно из индекса.

Это принципиально. HEAD участвует в результате только косвенно: если индекс совпадает с HEAD (то есть git diff --staged выдаёт пустой вывод), то рабочий файл окажется таким же, как в последнем коммите. Но это следствие совпадения, а не прямое обращение к коммиту.

Проверить, чист ли индекс, можно одной командой:

git diff --staged

Пустой вывод означает: записей в индексе, отличающихся от HEAD, нет. В таком состоянии git restore notes.txt и вернёт именно HEAD-версию файла — но только потому, что индекс её и содержит.

Если же в индексе уже лежит staged-версия notes.txt, отличающаяся от HEAD, — git restore notes.txt восстановит рабочий файл именно до этой staged-версии. Это не ошибка команды, это её точное поведение: источник фиксирован, и это всегда индекс.

Сам индекс команда не изменяет. Что там было — то и останется. Меняется только рабочая папка.

Выполнение git restore и проверка результата

Синтаксис команды минимален:

git restore <путь>

Флаг --staged не указывается. Именно его отсутствие определяет, что изменится рабочая папка, а не индекс.

Файл должен быть отслеживаемым, то есть присутствовать в индексе — иначе команда завершится ошибкой.

Создайте новую отдельную учебную папку и откройте в ней терминал. Выполните команды по одной:

git init -b main
git config user.name "Учебный автор"
git config user.email "learner@example.invalid"

В обычном текстовом редакторе создайте notes.txt со строкой «Первая версия», сохраните файл. Затем выполните:

git add notes.txt
git commit -m "init"
git status

В этой папке main содержит один коммит, файл отслеживается, рабочая папка и индекс чисты. Проверьте пустой git diff --staged. В редакторе добавьте в notes.txt строку «Лишняя правка» и сохраните, но add не выполняйте. Также создайте и сохраните draft.txt с любым учебным текстом; в индекс его не добавляйте.

Шаг 1. Смотрим на правку:

git diff

Вывод покажет примерно следующее:

diff --git a/notes.txt b/notes.txt
index ...  100644
--- a/notes.txt
+++ b/notes.txt
@@ -1 +1,2 @@
 Первая версия
+Лишняя правка

Это момент явного решения: вы прочитали правку и решили от неё отказаться.

Шаг 2. Сбрасываем рабочий файл:

git restore notes.txt

Команда не выводит ничего — это нормально. Строка «Лишняя правка» исчезла из рабочего файла безвозвратно: Git не сохраняет предыдущий рабочий текст автоматически.

Шаг 3. Проверяем двумя командами.

git diff

Вывод пустой: рабочий файл совпадает с индексом.

git status

Пример вывода:

On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        draft.txt

nothing added to commit but untracked files present (use "git add" to track)

Отслеживаемых правок больше нет, но весь status не чистый: untracked-файл остаётся. notes.txt больше не числится в «Changes not staged for commit». draft.txt по-прежнему виден в «Untracked files» — команда его не тронула.

Когда в индексе staged-версия: restore вернёт не HEAD

Предположим, вы уже добавили правку в индекс через git add, а потом продолжили редактировать файл и теперь хотите «вернуть всё как было в коммите». Интуитивно кажется, что git restore notes.txt должен восстановить версию из HEAD. Но это не так.

Команда возьмёт то, что лежит в индексе прямо сейчас — то есть staged-версию, отличающуюся от HEAD. Рабочая правка поверх staged будет выброшена, а staged-версия останется в индексе нетронутой.

Если рабочий файл уже совпадает со staged-версией, git restore notes.txt вообще ничего не изменит — перезаписывать нечего.

Чтобы действительно вернуть файл к состоянию HEAD, нужны два шага:

git restore --staged notes.txt

Эта команда сбросит запись в индексе обратно к HEAD. Затем:

git restore notes.txt

Теперь источник в индексе совпадает с HEAD, и рабочий файл получит именно эту версию.

Перед вторым шагом имеет смысл выполнить git diff, чтобы убедиться, что вы видите и намеренно отбрасываете текущую рабочую правку — она исчезнет без возможности автоматического восстановления.

Граница применимости: неотслеживаемые файлы команде недоступны

git restore <путь> работает только с файлами, у которых есть запись в текущем индексе. Если записи нет — команда не может взять версию «из индекса» и сообщит об ошибке:

error: pathspec 'draft.txt' did not match any file(s) known to git

Это не значит, что файл никогда не существовал в истории. Достаточно того, что в нынешнем индексе его записи нет — и команда отказывается работать.

Важно понять, что git restore notes.txt никак не влияет на соседние untracked-файлы вроде draft.txt. Они остаются на диске ровно в том состоянии, в котором были. Команда точечная: она действует только на указанный путь, и только если он отслеживается.

Поэтому после восстановления notes.txt в git status по-прежнему виден draft.txt в разделе «Untracked files» — именно так и должно быть.

Задача 1

У отслеживаемого report.txt рабочая версия — В, индекс — Б, последний коммит — А. В и Б отличаются. Выполнили только git restore report.txt без флагов. Какая тройка версий получится?

Выберите один вариант
Без регистрации · результат не сохраняется

Задача 2

Практика: создайте отдельный репозиторий с базовым коммитом notes.txt известными командами; используйте обе локальные настройки автора и обычный редактор. Измените notes.txt, но не добавляйте правку в индекс. Создайте новый draft.txt, тоже не добавляя его. Проверьте diff, восстановите только notes.txt и проверьте результат. Запишите обычный diff до и после восстановления и status, отдельно проверьте наличие нового draft.txt. Письменно объясните коллеге восстановление из staged-версии и порядок известных команд для возврата именно к HEAD.

Платформа проверяет только ответ ниже; действия в своём репозитории и письменные ответы вы проверяете самостоятельно.

В другом контрольном случае до обычного restore report.txt индекс содержал подготовленную версию Б, а HEAD — А. После restore обычный diff пуст. Что можно утверждать о git diff --staged для report.txt?

Выберите один вариант
Без регистрации · результат не сохраняется

Продолжить с сохранением прогресса

Перейдите к уроку в учебном кабинете.

Перейти к интерактивному уроку