Вы сможете восстановить любые файлы, которые вы добавили в индекс (например, как в вашей ситуации с git add .
), хотя это может быть немного трудоемким.Чтобы добавить файл в индекс, git добавляет его в базу данных объектов, что означает, что он может быть восстановлен, если сборка мусора еще не произошла.Пример того, как это сделать, приведен в ответе Якуба Наребски здесь:
Однако я попробовал это в тестовом репозитории, и возникла пара проблем - --cached
должно быть --cache
, и я обнаружил, что на самом деле он не создает каталог .git/lost-found
,Тем не менее, следующие шаги работали для меня:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)")
Это должно вывести все объекты в базе данных объектов, которые недоступны ни одному из ссылок, ни в индексе, ни через журнал ссылок.Вывод будет выглядеть примерно так:
unreachable blob 907b308167f0880fb2a5c0e1614bb0c7620f9dc3
unreachable blob 72663d3adcf67548b9e0f0b2eeef62bce3d53e03
... и для каждого из этих BLOB-объектов вы можете выполнить:
git show 907b308
Для вывода содержимого файла.
Слишком большой вывод?
Обновление в ответ на комментарий sehe ниже:
Если вы обнаружите, что выЕсли в выводе этой команды указано много коммитов и деревьев, вы можете удалить из вывода любые объекты, на которые ссылаются коммиты, на которые нет ссылок.(Обычно вы можете вернуться к этим коммитам через 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
(Обратите внимание, что вам нужно удалить /
в конце пути, чтобы получить имя объекта.)