Вопрос: Найти и восстановить удаленный файл в репозитории Git


Скажем, я в репозитории Git. Я удаляю файл и фиксирую это изменение. Я продолжаю работать и делаю еще несколько попыток. Затем, я считаю, мне нужно восстановить этот файл.

Я знаю, что могу проверить файл, используя git checkout HEAD^ foo.bar, но я действительно не знаю, когда этот файл был удален.

  1. Какой бы самый быстрый способ найти фиксацию, которая удалила данное имя файла?
  2. Каким будет самый простой способ вернуть этот файл в мою рабочую копию?

Я надеюсь, что мне не нужно вручную просматривать мои журналы, проверять весь проект для данной SHA, а затем вручную скопировать этот файл в мою первоначальную проверку проекта.


2354


источник


Ответы:


Найдите последнюю фиксацию, которая повлияла на данный путь. Поскольку файл не находится в фиксации HEAD, эта фиксация должна удалить его.

git rev-list -n 1 HEAD -- <file_path>

Затем проверьте версию в фиксации раньше, используя каретку ( ^) символ:

git checkout <deleting_commit>^ -- <file_path>

Или в одной команде, если $fileэто файл.

git checkout $(git rev-list -n 1 HEAD -- "$file")^ -- "$file"

Если вы используете zsh и включили опцию EXTENDED_GLOB, символ каретки не будет работать. Вы можете использовать ~1вместо.

git checkout $(git rev-list -n 1 HEAD -- "$file")~1 -- "$file"

2681



  1. использование git log --diff-filter=D --summaryполучить все коммиты, которые удалили файлы и удалили файлы;
  2. использование git checkout $commit~1 filenameдля восстановления удаленного файла.

где $commitэто значение фиксации, которое вы обнаружили на шаге 1, например. e4cf499627


712



Чтобы восстановить все эти удаленные файлы в папке, введите следующую команду.

git ls-files -d | xargs git checkout --

300



Я пришел к этому вопросу, пытаясь восстановить файл, который я только что удалил, но еще не внес изменений. На всякий случай, когда вы окажетесь в этой ситуации, все, что вам нужно сделать, это следующее:

git checkout HEAD -- path/to/file.ext


98



Если вы сумасшедший, используйте git-bisect, Вот что делать:

git bisect start
git bisect bad
git bisect good <some commit where you know the file existed>

Теперь пришло время запустить автоматизированный тест. Команда оболочки '[ -e foo.bar ]'вернет 0, если foo.barсуществует и 1 в противном случае. Команда «запустить» git-bisectбудет использовать двоичный поиск для автоматического поиска первого коммита, в котором тест завершится с ошибкой. Он начинается на полпути через заданный диапазон (от хорошего до плохого) и сокращает его пополам на основании результата указанного теста.

git bisect run '[ -e foo.bar ]'

Теперь вы используете фиксацию, которая удалила ее. Отсюда вы можете вернуться в будущее и использовать git-revertчтобы отменить изменение,

git bisect reset
git revert <the offending commit>

или вы можете вернуться назад и вручную проверить повреждение:

git checkout HEAD^
cp foo.bar /tmp
git bisect reset
cp /tmp/foo.bar .

82



Мой новый любимый псевдоним, основанный на bonyiii «s ответ (upvoted), и мой собственный ответ о " Передайте аргумент команде Git alias «:

git config alias.restore '!f() { git checkout $(git rev-list -n 1 HEAD -- $1)~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- $1)~1 | grep '^D' | cut -f 2); }; f'

Я потерял файл, удаленный по ошибке несколькими коммитами назад?
Быстро:

git restore my_deleted_file

Кризис предотвращен.


Роберт Дайли предлагает в комментариях следующий псевдоним:

restore-file = !git checkout $(git rev-list -n 1 HEAD -- "$1")^ -- "$1"

А также Jegan добавляет в комментариях :

Для установки псевдонима из командной строки я использовал эту команду:

git config --global alias.restore "\!git checkout \$(git rev-list -n 1 HEAD -- \"\$1\")^ -- \"\$1\"" 

60



If you know the filename, this is an easy way with basic commands:

List all the commits for that file.

git log -- path/to/file

The last commit (topmost) is the one that deleted the file. So you need to restore the second to last commit.

git checkout {second to last commit} -- path/to/file

41



To restore a deleted and commited file:

git reset HEAD some/path
git checkout -- some/path

It was tested on Git version 1.7.5.4.


27