Восстановление добавленного файла после выполнения git reset --hard HEAD ^ - PullRequest
58 голосов
/ 10 июля 2009

Я добавил новый файл F1 и внес изменения в другой файл F2, но затем произвел «git reset --hard HEAD ^», и я потерял все изменения в файлах.

Есть ли НЕКОТОРЫЙ способ, я могу вернуть их.

Я посмотрел на связанный вопрос здесь: Как мне отменить git reset --hard HEAD ~ 1? , но этот вопрос предполагает, что тот сделал git commit.

Ответы [ 5 ]

97 голосов
/ 10 июля 2009

Вы можете (с некоторой работой) восстановить состояние файла при последнем "git add ". Вы можете использовать

$ git fsck --cache --no-reflogs --lost-found --unreachable  HEAD

и затем проверьте файлы в каталоге .git / lost-found / other.

Пожалуйста, прочитайте git fsck manpage.

24 голосов
/ 18 марта 2013

(я предполагаю, что отсутствующий файл не является частью какого-либо коммита. В противном случае git log --all -g --diff-filter=D --stat ваш друг.)

  1. Получить список недоступных файлов, которым 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
    
  2. Если вы видите что-то интересное, 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>.

5 голосов
/ 31 января 2016

Существует git plugin, который делает это из коробки:

https://github.com/pendashteh/git-recover-index

$ cd /path/to/disatered/repo
$ git clone git@github.com:pendashteh/git-recover-index.git $HOME/.git-recover-index
$ $HOME/.git-recover-index/git-recover-index.sh
4 голосов
/ 23 июля 2013

Попробуйте это http://gitready.com/advanced/2009/01/17/restoring-lost-commits.html

У меня сердечный приступ из-за изменений, которые я потерял. Но после этого поста. Я получил свои изменения обратно

4 голосов
/ 10 июля 2009

На самом деле, если вы добавили объект в индекс (с помощью git add), для этого состояния объекта создается большой двоичный объект, но нет объекта дерева (и, следовательно, фиксации), который ссылается на Это. Вот как можно получить «болтающийся» свободный объектный файл, и если вы запустите git fsck, он покажет вам не имеющий ссылки блоб (git gc удалит эти типы объектов, если он будет запущен).

Из-за этого вы можете использовать reflog, если он у вас включен, чтобы попытаться восстановить состояние индекса для добавленного вами файла F1. Если вы вообще не добавили F2, то, как сказал Грег, git ничего об этом не знает, и вам не повезло.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...