Другое

Как восстановить удаленные файлы в Git: Полное руководство

Узнайте, почему git checkout . не восстанавливает удаленные файлы и изучите правильные команды Git для восстановления удаленных файлов. Полное руководство с пошаговыми решениями для восстановления файлов в Git.

Как восстановить удаленные файлы в Git, если после удаления не было сделано коммита?

Я удалил некоторые файлы, но еще не сделал коммит. Я пытался сбросить рабочую область с помощью git checkout ., чтобы восстановить файлы, но они все еще отсутствуют. Когда я запускаю git status, он показывает:

# На ветке master
# Изменения для коммита:
#   (используйте "git reset HEAD <file>...", чтобы отменить индексацию)
#
#   удалено:    cc.properties
#   удалено:    store/README
#   удалено:    store/cc.properties
#

Почему git checkout . не сбрасывает рабочую область к HEAD в этом сценарии, и какой правильный способ восстановить эти удаленные файлы?

git checkout . восстанавливает файлы только из индекса в рабочую директорию, но не восстанавливает файлы, которые были удалены и проиндексированы. Чтобы восстановить эти удаленные файлы, сначала нужно убрать их из индекса с помощью git restore --staged <file> или git reset HEAD <file>, а затем восстановить их в рабочую директорию с помощью git restore <file>.

Содержание

Понимание проблемы

Когда вы удаляете файлы в Git и индексируете эти удаления (либо явно с помощью git add, либо неявно через поведение Git по умолчанию), вы работаете с областью подготовки (также называемой индексом). Область подготовки отделена как от вашей рабочей директории, так и от последнего коммита.

Ключевое здесь заключается в том, что ваши файлы существуют в двух состояниях:

  1. Рабочая директория: Файлы, которые вы фактически видите и редактируете
  2. Область подготовки: Файлы, подготовленные для следующего коммита

Когда вы удаляете файлы и индексируете эти удаления, Git помечает их как “удаленные” в области подготовки, даже если они больше не существуют в вашей рабочей директории. Это создает разрыв, который git checkout . не может разрешить самостоятельно.


Почему git checkout . не сработал

git checkout . (или его современный эквивалент git restore .) работает путем сравнения вашей рабочей директории с областью подготовки и восстановления любых различий. Однако в вашем случае:

  1. Файлы уже удалены в рабочей директории
  2. Файлы также помечены как удаленные в области подготовки
  3. Поскольку оба состояния совпадают (оба показывают “удалено”), Git не видит различий для восстановления

Важно: git checkout . восстанавливает файлы только из области подготовки в рабочую директорию. Он не взаимодействует с файлами, которые ранее были закоммичены, но были изменены или удалены в области подготовки.

Вот почему ваши файлы по-прежнему отсутствуют - в области подготовки нет “источника” для восстановления, поскольку вы уже проиндексировали удаления.


Правильные методы восстановления

Метод 1: Использование git restore (Рекомендуется для Git 2.23+)

Современный подход использует git restore, который был введен в Git 2.23 для предоставления более четкого интерфейса для этих операций:

bash
# Сначала убираем удаления из индекса
git restore --staged cc.properties store/README store/cc.properties

# Затем восстанавливаем файлы в рабочую директорию
git restore cc.properties store/README store/cc.properties

Или можно сделать это в два отдельных шага:

bash
# Убираем удаления из индекса
git restore --staged .

# Восстанавливаем все файлы из последнего коммита
git restore .

Метод 2: Использование git reset

Для старых версий Git или если вы предпочитаете традиционный подход:

bash
# Убираем удаления из индекса (но оставляем их в рабочей директории)
git reset HEAD cc.properties store/README store/cc.properties

# Восстанавливаем файлы из последнего коммита
git checkout cc.properties store/README store/cc.properties

Или проще:

bash
# Убираем все изменения из индекса
git reset HEAD

# Восстанавливаем все файлы из последнего коммита
git checkout .

Метод 3: Восстановление отдельных файлов

Если вы хотите восстановить только определенные файлы:

bash
# Для каждого файла убираем из индекса и восстанавливаем
git restore --staged cc.properties && git restore cc.properties
git restore --staged store/README && git restore store/README  
git restore --staged store/cc.properties && git restore store/cc.properties

Альтернативные подходы

Использование git checkout с конкретными файлами

Если вы хотите быть более точным:

bash
# Убираем удаления из индекса
git reset HEAD cc.properties store/README store/cc.properties

# Выполняем checkout конкретных файлов из HEAD
git checkout cc.properties
git checkout store/README
git checkout store/cc.properties

Использование git fsck для восстановления

В более сложных сценариях, когда файлы могут быть ссылаться в других местах:

bash
# Находим объекты, которые можно восстановить
git fsck --lost-found

# Это создает директорию lost+found с потенциально восстанавливаемыми объектами

Предотвращение будущих проблем

Понимание модели подготовки Git

Чтобы избежать путаницы в будущем, запомните трехуровневую модель Git:

Рабочая директория → Область подготовки → История коммитов
  • git add перемещает изменения из рабочей директории в область подготовки
  • git commit перемещает изменения из области подготовки в историю коммитов
  • git checkout/git restore перемещает изменения из области подготовки в рабочую директорию

Использование git restore для ясности

Современная команда git restore предоставляет более четкую семантику:

  • git restore --staged <file>: Удалить из области подготовки
  • git restore <file>: Восстановить из области подготовки в рабочую директорию
  • git restore --source=HEAD <file>: Восстановить непосредственно из HEAD в рабочую директорию

Безопасные практики удаления

Перед удалением важных файлов:

bash
# Проверяем, какие файлы будут затронуты
git status

# Рассмотрите возможность создания резервного коммита
git add -p  # Интерактивная индексация
git commit -m "Резервная копия перед очисткой"

Источники

  1. Официальная документация Git - git-restore
  2. Книга Pro Git - Область подготовки
  3. Документация Git - git-checkout
  4. Учебник Git от Atlassian - Отмена изменений

Заключение

Ключевой вывод заключается в том, что git checkout . восстанавливает файлы только из области подготовки в рабочую директорию, но не может восстановить файлы, которые были удалены и проиндексированы. Чтобы восстановить удаленные файлы, вам нужно:

  1. Сначала убрать удаления из индекса с помощью git restore --staged <file> или git reset HEAD <file>
  2. Затем восстановить файлы с помощью git restore <file> или git checkout <file>

Для современных версий Git (2.23+) команда git restore --staged . followed by git restore . предоставляет наиболее четкий подход. Понимание трехуровневой модели Git (рабочая директория, область подготовки и история коммитов) поможет избежать подобной путаницы в будущем. Всегда проверяйте с помощью git status перед выполнением разрушительных операций и рассмотрите возможность создания резервных коммитов при работе с важными файлами.

Авторы
Проверено модерацией
Модерация