Вопрос по git – Восстановите файлы, которые были добавлены в индекс, но затем удалены при помощи git reset

9

Я добавил некоторые файлы в индекс, но потом по ошибке удалил ихgit reset --hard, Как мне их восстановить? Вот что случилось:

I added all files using git add . I then committed When I checked the status, there were still files that weren't included in the commit from the add, which was strange I added the untracked files again and it worked this time But I wanted everything to be in 1 single commit so I looked up how to unstage what I just committed I used git reset --hard HEAD^ — bad idea obviously, all files were deleted so then I used git reflog to find where I left off then I used git reflog ______ to go back to my last commit. then I used git reset HEAD to unstage the commit (what I should have originally done) but the files I added (see above) after the commit were still gone.

Как мне вернуть эти файлы?

Смотрите такжеRecovering added file after doing git reset --hard HEAD^. user456814
Вы можете стать счастливчиком, запустивgit fsck --full и немного терпения, просеивая через все эти недосягаемые капли, о которых он собирается сообщить. knittl
Если они никогда не были зафиксированы, и вы сбросили индекс, возможно, вы не сможете. Ashe
Есть ли способ отменить сброс индекса? Jeff Eisley

Ваш Ответ

2   ответа
21

First, make a full backup of your Git repository!

Когда тыgit add git создаст BLOB-объект из содержимого этого файла и добавит его в свою объектную базу данных (.git/objects/??/*).

Давайте посмотрим на ваши команды, одну за другой:

I added all files using git add .

$ git add .

Это добавит все файлы, содержащиеся в текущем каталоге и его подкаталогах, в базу данных объектов Git. Файлы без отслеживания, соответствующие шаблонам из.gitignore файлы не будут добавлены. Дерево файлов также будет записано. Пожалуйста, посмотрите конец моего ответа.

I then committed

$ git commit -m'added all files'

Это запишет новый объект коммита в базу данных объектов. Этот коммит будет ссылаться на одно дерево. Дерево ссылается на BLOB-объекты (файлы) и другие деревья (подкаталоги).

When I checked the status, there were still files that weren't included in the commit from the add, which was strange

$ git status

Я могу придумать два сценария, где это происходит: что-то изменило ваши файлы или новые файлы были добавлены за вашей спиной.

I added the untracked files again and it worked this time

$ git add .

Я полагаю, вы использовали то же самоеadd снова введите команду, как в шаге 1.

But I wanted everything to be in 1 single commit so I looked up how to unstage what I just committed

Я расскажу вам лучший способ в конце этого ответа, который не требует от пользователя выдавать потенциально опасныйreset

I used git reset --hard HEAD^ — bad idea obviously, all files were deleted

$ git reset --hard HEAD^

Эта команда установит ваше текущее рабочее дерево и индекс точно на коммитHEAD^ (второй-последний коммит). Другими словами, он отбросит все локальные незафиксированные изменения и переместит указатель ветви на один коммит. Не трогает неотслеживаемые файлы.

so then I used git reflog to find where I left off

$ git reflog

Это показывает последние коммиты, которые были недавно извлечены (идентичноgit reflog HEAD). Если вы укажете имя ветви, она покажет вам последние коммиты, на которые недавно указала эта ветка.

then I used git reflog __ to go back to my last commit.

Не уверен насчет этого.git reflog является (в основном) командой только для чтения и не может использоваться для "возврата" совершать. Вы можете использовать только его, чтобы найти коммит ветку (илиHEAD) указал на.

then I used git reset HEAD to unstage the commit (what I should have originally done) but the files I added (see above) after the commit were still gone. $ git reset HEAD

Это не приведет к отмене удаления этой фиксации, но приведет к отмене всех поэтапных (но не принятых) изменений из индекса. Первоначально (1-й шаг), вы хотели сказатьgit reset HEAD^ (или жеgit reset --mixed HEAD^) & # x2013; это оставит ваше рабочее дерево нетронутым, но установите индекс в соответствии с деревом, на которое указывает коммит, названныйHEAD^.


Теперь, чтобы вернуть ваши файлы, вы должны использоватьgit fsck --full --unreachable --no-reflog, Он будет сканировать все объекты в базе данных объектов Git и выполнять анализ достижимости. Вы хотите искатьblob объекты. Там также должно бытьtree объект, описывающий состояние после вашего второгоgit add .

git cat-file -p <object hash> будет печатать содержимое файлов, чтобы вы могли убедиться, что у вас есть нужные объекты. Для больших двоичных объектов вы можете использовать перенаправление ввода-вывода, чтобы записать содержимое в правильное имя файла. Для деревьев вы должны использовать команды git (git read-tree). Если в нем всего несколько файлов, лучше записать их непосредственно в файлы.


Несколько заметок здесь:

Если вы хотите добавить файлы в последний коммит (или отредактировать его сообщение о коммите), вы можете просто использоватьgit commit --amend, Это в основном обертка вокругgit reset --soft HEAD^ && git commit -c [email protected]{1}.

Кроме того, это почти никогда не является хорошей идеей для использованияgit add ., Обычно вы хотите использовать его только в первый раз, когда создаете новый репозиторий. Лучшие альтернативыgit add -u, git commit -a, который будет вносить все изменения в отслеживаемые файлы. Чтобы отслеживать новые файлы, лучше указывайте их явно.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Jeff Eisley
Error: User Rate Limit Exceeded Jeff Eisley
15

У меня была похожая проблема, но у меня было много висящих пятен и деревьев в моем репо, поэтому я в итоге отфильтровалgrep вывод всех свисающих капель и печать тех, которые совпадают. Если предположить,${UNIQUE_CODE} это какой-то код, который уникален для файлов, которые у вас были в индексе, тогда он должен дать вам хэши искомых BLOB-объектов:

for b in $(git fsck --lost-found | grep blob | awk '{print $3}'); do git cat-file -p $b | grep -q ${UNIQUE_CODE} && echo $b; done
Error: User Rate Limit Exceeded

Похожие вопросы