(я предполагаю, что отсутствующий файл не является частью какого-либо коммита. В противном случае git log --all -g --diff-filter=D --stat
ваш друг.)
Получить список недоступных файлов, которым git
известно имя файла:
git fsck --unreachable --no-reflogs --no-cache HEAD | fgrep " tree " \
| cut -d " " -f3 | xargs -r -n1 git ls-tree \
| fgrep " blob " | cut -d " " -f 3- | sort -k2 -u
Если вы видите что-то интересное, git cat-file blob SHA-1-of-interesting-file
выведет файл на стандартный вывод. (Пример: git cat-file blob b8f0bdf56 > recovered-logo.png
)
К сожалению, если отсутствующий файл не является частью какого-либо коммита, у git нет метки времени, и поэтому вы не можете распечатать различные версии файлов, упорядоченные по времени.
Если отсутствующий файл никогда не был размещен (git stage
или git add
) или спрятан (git stash
), вам почти не повезло, потому что, насколько известно git, файл никогда не существовал. (Вы все еще можете попробовать сделать git fsck --no-reflogs --lost-found
и поискать в каталоге .git/lost-found/other
, чтобы узнать, есть ли у вас что-то, что стоит сохранить на тот случай, если в git действительно есть копия вашего отсутствующего файла по случайной случайности. У вас нет имен файлов, чтобы помочь у вас в этом случае только содержимое файла.)
В случае, если вы только что потеряли некоторые коммиты (а не только файлы), вы, вероятно, захотите запустить что-то вроде этого:
gitk --all $( git fsck | awk '/dangling commit/ {print $3}'; git log -g --pretty='format:%H' )
Это запустит gitk
со всеми ветками, всеми reflog и всеми висячими коммитами. Возможно, вы захотите добавить -n 10000
или какой-либо другой предел, если в вашем репо действительно много коммитов (скажем, в ядре Linux). Если у вас нет gitk
, вы можете запустить меньшую версию, используя только командную строку, например:
git log --all --decorate --stat --graph --date-order $( git fsck | awk '/dangling commit/ {print $3}'; git log -g --pretty='format:%H' )
или версия с менее подробным выводом
git log --all --decorate --oneline --graph --date-order $( git fsck | awk '/dangling commit/ {print $3}'; git log -g --pretty='format:%H' )
Если вы видите коммит, который хотите сохранить как ветку recovered1
, просто выполните git checkout -b recovered1 <sha1-of-the-commit>
.