Вы должны иметь возможность восстанавливать любые файлы, которые вы добавили в индекс (например, как в вашей ситуации git add .
), хотя это может потребовать некоторой работы. Чтобы добавить файл в индекс, git добавляет его в базу данных объектов, что означает, что он может быть восстановлен, если еще не произведена сборка мусора. Вот пример того, как это сделать, приведен в ответе Якуба Наребски здесь:
Однако я попробовал это в тестовом репозитории, и возникла пара проблем - --cached
должно быть --cache
, и я обнаружил, что на самом деле .git/lost-found
каталог не создавался . Однако у меня сработали следующие шаги:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)")
Это должно вывести все объекты в базе данных объектов, которые недоступны ни по какой ссылке, в индексе или через журнал ссылок. Результат будет выглядеть примерно так:
unreachable blob 907b308167f0880fb2a5c0e1614bb0c7620f9dc3
unreachable blob 72663d3adcf67548b9e0f0b2eeef62bce3d53e03
... и для каждой из этих капель вы можете:
git show 907b308
Чтобы вывести содержимое файла.
Слишком много вывода?
Обновление в ответ на sehe «s комментарий ниже:
Если вы обнаружите, что у вас есть много коммитов и деревьев, перечисленных в выходных данных этой команды, вы можете удалить из выходных данных любые объекты, на которые есть ссылки из коммитов без ссылок. (Обычно вы все равно можете вернуться к этим коммитам через reflog - нас просто интересуют объекты, которые были добавлены в индекс, но никогда не могут быть найдены с помощью фиксации.)
Сначала сохраните вывод команды с помощью:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") > all
Теперь имена объектов этих недостижимых коммитов можно найти с помощью:
egrep commit all | cut -d ' ' -f 3
Таким образом, вы можете найти только деревья и объекты, которые были добавлены в индекс, но не зафиксированы в какой-либо момент, с помощью:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") \
$(egrep commit all | cut -d ' ' -f 3)
Это значительно сокращает количество объектов, которые вам нужно учитывать.
Обновление: Филип Окли ниже предлагает другой способ сократить количество объектов для рассмотрения, а именно рассматривать файлы, которые были недавно изменены .git/objects
. Вы можете найти их с помощью:
find .git/objects/ -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort
(Я нашел этот find
вызов здесь .) Конец этого списка может выглядеть так:
2011-08-22 11:43:43.0234896770 .git/objects/b2/1700b09c0bc0fc848f67dd751a9e4ea5b4133b
2011-09-13 07:36:37.5868133260 .git/objects/de/629830603289ef159268f443da79968360913a
В этом случае вы можете увидеть эти объекты с помощью:
git show b21700b09c0bc0fc848f67dd751a9e4ea5b4133b
git show de629830603289ef159268f443da79968360913a
(Обратите внимание, что вам нужно удалить /
символ в конце пути, чтобы получить имя объекта.)