Вернуть файл как в последнем коммите
Чтобы отменить изменения в файле, которые вы ещё не закоммитили, используйте git restore <файл>: команда возвращает файл к сохранённой версии, и все правки пропадают. Разберём три ситуации: правка получилась неудачной, в индекс попало лишнее, а в только что сделанном коммите опечатка или не хватает файла. Раньше git status подсказывал нужные команды, но мы только читали подсказки и шли дальше, а теперь пора ими пользоваться.
Простыми словами
Это как «вернуть к сохранённому» в игре: вы пробовали что-то рискованное, не понравилось, и файл снова такой, каким был при последней фиксации. Только у такой «загрузки» нет второй попытки, и это важно запомнить сразу.
Официальный термин и пример
Команда git restore (restore — «восстановить») возвращает файлы рабочей папки к сохранённой версии. Допустим, вы экспериментировали и случайно испортили заголовок в index.html:
$ git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
$ git diff
diff --git a/index.html b/index.html
index 5b596b8..6025cc0 100644
--- a/index.html
+++ b/index.html
@@ -6,7 +6,7 @@
<link rel="stylesheet" href="style.css">
</head>
<body>
- <h1>Алекс Иванов</h1>
+ <h1>Алекс Иванов??</h1>
<p class="lead">Начинающий веб-разработчик</p>
<section id="about">
<h2>Обо мне</h2>
$ git restore index.html
$ git status
On branch main
nothing to commit, working tree clean
Разбор по строкам
modified: index.htmlи подсказкаuse "git restore <file>..." to discard changes— Git сам называет команду для отмены. Слово discard значит «отбросить».git diffпоказывает, что именно пропадёт: лишние знаки вопроса в заголовке. Перед отменой на него стоит взглянуть.git restore index.html— команда молчит, как и большинство команд Git при успехе.working tree clean— файл снова совпадает с последним коммитом, а заголовок прежний.
Корзины нет
Правки, отброшенные через git restore, пропадают насовсем: Git никогда их не сохранял, ведь они не были закоммичены. Прежде чем отменять, посмотрите git diff. И не пишите git restore ., если не уверены: точка означает «все файлы сразу».
Убрать файл из индекса
Вторая ситуация: вы выполнили git add . и вместе с нужным файлом подготовили к коммиту лишний. Правки в файле жалко не терять, нужно лишь снять файл с «сцены» (индекса). Допустим, вы дописали строку в README.md и поэкспериментировали со стилями, а git add . взял всё сразу:
$ git add .
$ git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: README.md
modified: style.css
$ git restore --staged style.css
$ git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: README.md
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: style.css
Разбор по строкам
use "git restore --staged <file>..." to unstage— подсказка Git: unstage значит «снять с подготовки». Флаг--stagedговорит, что действовать нужно на индекс, а не на рабочую папку.- После
git restore --staged style.cssфайл ушёл в разделChanges not staged for commit. Правка в нём сохранилась: мы лишь передумали включать её в коммит. README.mdостался в индексе, и в следующий коммит пойдёт только он.
Если эксперимент в style.css вам не нужен совсем, теперь можно отбросить и его — первой командой из этого урока:
$ git restore style.css
Различие запомните по одной мысли: без флага git restore меняет файл на диске (правки пропадают), с --staged — только индекс (правки остаются).
| Команда | Что происходит | Правки в файле |
|---|---|---|
git restore файл | файл на диске становится таким же, как в индексе (а если файл не добавляли — как в последнем коммите) | пропадают |
git restore --staged файл | файл убирается из индекса, то есть из будущего коммита | остаются |
Откуда два разных совета в git status
До первого коммита git status советовал убрать файл из индекса командой git rm --cached: тогда ещё не было коммита, с которым можно сравнить. После первого коммита подсказка заменяется на git restore --staged. Смысл один: снять файл с подготовки.
Поправить последний коммит: git commit --amend
Третья ситуация случается постоянно: коммит сделан, и тут же видно опечатку в подписи или забытый файл. Делать для этого новый «исправляющий» коммит не обязательно. Это как переклеить ярлык на только что запакованной коробке или доложить в неё забытую вещь. Команда git commit --amend (amend — «исправить», «дополнить») заменяет последний коммит новым.
Опечатка в сообщении
Допустим, вы добавили в README строку «Страница на чистом HTML и CSS, без фреймворков.» и закоммитили её с опечаткой в подписи:
$ git commit -m "Добавить описанеи сайта"
[main 0ca1cfc] Добавить описанеи сайта
1 file changed, 2 insertions(+)
$ git commit --amend -m "Добавить описание сайта"
[main 1dbd335] Добавить описание сайта
Date: Tue Nov 10 13:00:00 2026 +0300
1 file changed, 2 insertions(+)
$ git log --oneline
1dbd335 (HEAD -> main) Добавить описание сайта
12d081f Добавить .gitignore
284ecf7 Исправить опечатку в заголовке
Разбор по строкам
--amend -m "…"— заменить подпись последнего коммита новым текстом. Если написать простоgit commit --amend, откроется редактор со старой подписью: исправьте её, сохраните и закройте окно.[main 1dbd335]— хеш другой, не0ca1cfc. Коммит не «отредактирован»: Git создал новый, а старый отложил в сторону. Именно поэтому хеш меняется.Date:— дата исходного коммита; эта строка при amend появляется нормально.- В
git logкоммит с опечаткой не виден: на его месте стоит исправленный.
Забытый файл
Вы вспомнили, что к тому же коммиту относится ещё одна правка: описание сайта для поисковиков в <head> файла index.html. Добавьте в index.html после строки с <title> такую строку:
<meta name="description" content="Визитка Алекса Иванова, начинающего веб-разработчика">
Подготовьте файл и допишите его в последний коммит, подпись при этом оставив прежней:
$ git add index.html
$ git commit --amend --no-edit
[main 746ac3d] Добавить описание сайта
Date: Tue Nov 10 13:00:00 2026 +0300
2 files changed, 3 insertions(+)
Разбор по строкам
git add index.html— обычная подготовка файла: amend берёт то, что лежит в индексе.--no-edit— не открывать редактор и не менять сообщение.2 files changed, 3 insertions(+)— теперь в коммите два файла:README.mdиindex.html. Хеш снова новый:746ac3d.
Amend переписывает историю: только для своего и неопубликованного
Amend подменяет коммит новым с другим хешем. Пока коммит живёт только на вашем компьютере, это безопасно. Но если вы уже отправили его кому-то (отправлять код на GitHub мы скоро научимся), у других людей останется старый коммит, и ваши истории разойдутся. Поэтому правило такое: amend — только для последнего коммита, которым ещё ни с кем не поделились.
Восстановить удалённый файл
Удалили файл по ошибке или скрипт стёр лишнее? Пока удаление не закоммичено, Git помнит файл. Попробуйте: удалите style.css из папки проекта и посмотрите на статус.
$ rm style.css
$ git status
On branch main
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: style.css
no changes added to commit (use "git add" and/or "git commit -a")
$ git restore style.css
$ git status
On branch main
nothing to commit, working tree clean
deleted: style.css — Git видит, что отслеживаемый файл исчез, и предлагает ту же самую git restore. Она ведёт себя так: «файла нет, значит, достать его заново из сохранённой версии». Если же файл был удалён уже давно и удаление закоммичено, достать его можно из прошлого коммита; об этом — в следующем уроке.
В старых статьях и ответах
В статьях до 2019 года вы встретите git checkout -- файл вместо git restore файл и git reset HEAD файл вместо git restore --staged файл. Это то же самое, старые команды по-прежнему работают. В курсе мы используем новые: у них понятнее названия.
Практика у себя
Пройдём все три ситуации подряд на визитке. После каждого шага сверяйтесь с git status.
- Старт. В
~/projects/portfolioвыполнитеgit status(должно бытьworking tree clean) иgit log --oneline(шесть коммитов, последний — «Добавить .gitignore»). - Испортите и отмените. В
index.htmlдопишите после «Алекс Иванов» в заголовкеh1два знака вопроса и сохраните. Выполнитеgit diff, затемgit restore index.html. Ожидаем:git statusснова чистый, в заголовке нет знаков вопроса. - Две правки, одна лишняя. Дополните
README.mdстрокойСтраница на чистом HTML и CSS, без фреймворков.через пустую строку после уже имеющейся. Вstyle.cssзаменитеcolor: #222;наcolor: hotpink;. Сохраните оба файла. - Всё в индекс, лишнее обратно. Выполните
git add ., затемgit restore --staged style.cssиgit status:README.mdв индексе,style.cssизменён, но не подготовлен. Эксперимент не нужен:git restore style.css. Теперьgit statusпоказывает толькоREADME.mdв разделеChanges to be committed. - Коммит с опечаткой. Сделайте
git commit -m "Добавить описанеи сайта"(опечатка намеренная), затем исправьте:git commit --amend -m "Добавить описание сайта". - Забытая правка. Добавьте в
index.htmlстроку с<meta name="description"…>из раздела про amend, затемgit add index.htmlиgit commit --amend --no-edit. Проверьте:git show --statперечисляет два файла. - Удалите и верните.
rm style.css,git status(должно бытьdeleted: style.css),git restore style.css. Файл на месте.
Итог (хеши у вас будут другие):
$ git log --oneline
746ac3d (HEAD -> main) Добавить описание сайта
12d081f Добавить .gitignore
284ecf7 Исправить опечатку в заголовке
cb00bb8 Добавить раздел «Мои проекты»
f58d529 Добавить README
8c23940 Добавить стили
027a150 Добавить главную страницу
Проверьте себя
git log --onelineпоказывает семь коммитов, последний — «Добавить описание сайта», без следов опечатки в подписи.git statusсообщаетnothing to commit, working tree clean;style.cssна месте и безhotpink.git show --statперечисляет в последнем коммитеREADME.mdиindex.html.- Вы можете объяснить, чем
git restore файлотличается отgit restore --staged файл.
Частые ошибки
error: pathspec '…' did not match any file(s) known to git. Git не нашёл такого файла среди отслеживаемых: опечатка в имени либо файл новый и никогда не попадал в коммит. Для нового файла restore бессилен, потому что восстанавливать нечего. Такой файл удаляют руками.
Вы отменили правку, а она нужна. Если команда была git restore файл без коммита, вернуть правки нельзя. В следующий раз смотрите git diff до отмены.
Перепутали --staged и без него. Хотели снять файл с подготовки, но написали git restore файл, и правки пропали. Хотели отбросить правки, но написали с --staged — ничего страшного: файл просто ушёл из индекса, а правки остались. Если сомневаетесь, начинайте с --staged.
Amend после того, как поделились коммитом. Подмена опубликованного коммита ломает историю у тех, кто успел его получить. Пока это только предупреждение, но оно станет важным, когда проект появится на GitHub.
Что важно запомнить
git restore <файл>отбрасывает правки в файле до сохранённой версии, без корзины; сначала смотритеgit diff.git restore --staged <файл>снимает файл с подготовки к коммиту, правки остаются.git commit --amend -m "…"меняет подпись последнего коммита,git add+git commit --amend --no-editдописывает в него забытое. Хеш при этом меняется.- Amend допустим только для последнего коммита, которым вы ни с кем не поделились.
- Удалённый файл возвращается той же
git restore <файл>. В старых статьях вместо неё встречаютсяcheckout -- файлиreset HEAD файл.
Всё это работало для последнего коммита и для правок, которые ещё не закоммичены. А как вернуться на несколько коммитов назад, посмотреть прошлое проекта и отменить старый коммит, не ломая остальную историю? Об этом — в следующем уроке.
Подробно — в документации: git restore, git commit (раздел про --amend).