Найти и восстановить удаленный файл в репозиторий Git
скажем, я в репозитории Git. Я удаляю файл и фиксирую это изменение. Я продолжаю работать и делаю еще несколько коммитов. Затем я считаю, что мне нужно восстановить этот файл.
Я знаю, что могу проверить файл с помощью git checkout HEAD^ foo.bar, но я действительно не знаю, когда этот файл был удален.
- каков был бы самый быстрый способ найти фиксацию, которая удалила данное имя файла?
- что было бы самым простым способом вернуть этот файл в мою работу понял?
Я надеюсь, что мне не нужно вручную просматривать мои журналы, проверять весь проект для данного SHA, а затем вручную копировать этот файл в мой исходный проект checkout.
19 ответов:
найти последний коммит, который повлиял на данном пути. Поскольку файл не находится в головном коммите, этот коммит должен был удалить его.
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"
- использовать
git log --diff-filter=D --summaryчтобы получить все коммиты, которые удалили файлы и файлы удалены;- использовать
git checkout $commit~1 filenameдля восстановления удаленного файла.здесь
$commitзначение фиксации вы нашли на шаге 1, например,e4cf499627
чтобы восстановить все удаленные файлы в папку, введите следующую команду.
git ls-files -d | xargs git checkout --
Я пришел к этому вопросу, чтобы восстановить файл, который я только что удалил, но я еще не совершил изменения. На всякий случай, если вы окажетесь в такой ситуации, все, что вам нужно сделать, это следующее:
git checkout HEAD -- path/to/file.ext
если вы сумасшедший, используйте
git-bisect. Вот что нужно сделать:git bisect start git bisect bad git bisect good <some commit where you know the file existed>теперь пришло время запустить автоматический тест. Команда оболочки
'[ -e foo.bar ]'вернет 0, если , и 1 в противном случае. Команда " run " из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 .
мой новый любимый псевдоним, основанный на bonyiii ' s ответ (голосуют), и мой собственный ответ о "передайте аргумент команде git alias":
git config alias.restore '!f() { git checkout $(git rev-list -n 1 HEAD -- )~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- )~1 | grep '^D' | cut -f 2); }; f'Я потерял файл, удаленный по ошибке несколько коммитов назад?
Быстро:git restore my_deleted_fileкризис миновал.
Роберт Дэйли предлагает в комментариях следующие псевдонимы:
restore-file = !git checkout $(git rev-list -n 1 HEAD -- "")^ -- ""и jegan добавляет в комментариях:
настройки псевдоним из командной строки, я использовал эту команду:
git config --global alias.restore "\!git checkout $(git rev-list -n 1 HEAD -- \"$1\")^ -- \"$1\""
Если вы знаете имя файла, это простой способ с помощью основных команд:
перечислите все коммиты для этого файла.
git log -- path/to/fileпоследняя фиксация (самая верхняя) - это та, которая удалила файл. Поэтому вам нужно восстановить предпоследнюю фиксацию.
git checkout {second to last commit} -- path/to/file
для восстановления удаленного и записанного файла:
git reset HEAD some/path git checkout -- some/pathОн был протестирован на Git версии 1.7.5.4.
Если вы только внесли изменения и удалили файл, но не зафиксировали его, и теперь вы расстались с вашими изменениями
git checkout -- .но ваши удаленные файлы не возвращаются, вы просто делаете следующую команду:
git checkout <file_path>и вуаля, ваш файл обратно.
у меня есть данное решение.
получить идентификатор фиксации, где файл был удален с помощью одного из способов ниже.
git log --grep=*word*git log -Swordgit log | grep --context=5 *word*git log --stat | grep --context=5 *word*# рекомендуется, если вы вряд ли запомните что-нибудьвы должны получить что-то вроде:
совершить bfe68bd117e1091c96d2976c99b3bcc8310bebe7 Автор: Александр Орлов Дата: Чт 12 Мая 23: 44: 27 2011 +0200
replaced deprecated GWT class - gwtI18nKeySync.sh, an outdated (?, replaced by a Maven goal) I18n generation scriptcommit 3ea4e3af253ac6fd1691ff6bb89c964f54802302 Автор: Александр Орлов Дата: Чт 12 Мая 22: 10: 22 2011 +0200
3. Теперь, используя идентификатор фиксации bfe68bd117e1091c96d2976c99b3bcc8310bebe7 do:
git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.javaпоскольку идентификатор фиксации ссылается на фиксацию, где файл уже был удален, вам нужно ссылаться фиксация непосредственно перед bfe68b, которую вы можете сделать, добавив
^1. Это означает: дайте мне фиксацию непосредственно перед bfe68b.
во многих случаях может быть полезно использовать coreutils (grep, sed и др.) в сочетании с Git. Я уже знаю эти инструменты довольно хорошо,но Git меньше. Если бы я хотел выполнить поиск удаленного файла, я бы сделал следующее:
git log --raw | grep -B 30 $'D\t.*deleted_file.c'когда я нахожу ревизию / фиксацию:
git checkout <rev>^ -- path/to/refound/deleted_file.cКак уже сказали до меня.
теперь файл будет восстановлен до состояния, в котором он находился до удаления. Не забудьте повторно зафиксировать его в рабочем состоянии дерево, если вы хотите сохранить его.
git undelete path/to/file.ext
положите это в ваш
.bash_profile(или другой соответствующий файл, который загружается при открытии командной оболочки):git config --global alias.undelete '!sh -c "git checkout $(git rev-list -n 1 HEAD -- )^ -- " -'затем использовать:
git undelete path/to/file.extэтот псевдоним сначала проверяет, чтобы найти последнюю фиксацию, где этот файл существовал, а затем выполняет проверку git этого пути к файлу из этой последней фиксации, где этот файл существовал. источник
поэтому мне пришлось восстановить кучу удаленных файлов из определенного коммита, и я справился с этим двумя командами:
git show <rev> --diff-filter=D --summary --name-only --no-commit-id | xargs git checkout <rev>^ -- git show <rev> --diff-filter=D --summary --name-only --no-commit-id | xargs git reset HEAD(обратите внимание на пробел в конце каждой команды.)
файлы были добавлены .файл gitignore, а затем очищенный с помощью git rm, мне нужно было восстановить файлы, но затем разархивировать их. У меня были сотни файлов для восстановления, ввод вручную для каждого файла, как и в других примерах, будет слишком медленным.
user@bsd:~/work/git$ rm slides.tex user@bsd:~/work/git$ git pull Already up-to-date. user@bsd:~/work/git$ ls slides.tex ls: slides.tex: No such file or directoryвосстановить удаленный файл:
user@bsd:~/work/git$ git checkout D .slides.tex.swp D slides.tex user@bsd:~/work/git$ git checkout slides.tex user@bsd:~/work/git$ ls slides.tex slides.tex
у меня был тот же вопрос. Сам того не зная, я создал свесив совершения.
список висячих коммитов
git fsck --lost-foundпроверьте каждый висячий фиксатор
git reset --hard <commit id>мои файлы снова появились, когда я перешел к Висячей фиксации.
git statusпо причине:
“HEAD detached from <commit id where it detached>”
в нашем случае мы случайно удалили файлы в фиксации и некоторые фиксации позже мы поняли нашу ошибку и хотели вернуть все файлы, которые были удалены, но не те, которые были изменены.
на основе превосходного ответа Чарльза Бейли вот мой один лайнер:
git co $(git rev-list -n 1 HEAD -- <file_path>)~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- <file_path>)~1 head | grep '^D' | cut -f 2)
Если вы знаете фиксацию, которая удалила файл(ы), выполните эту команду, где
<SHA1_deletion>это фиксация, которая удалила файл:git diff --diff-filter=D --name-only <SHA1_deletion>~1 <SHA1_deletion> | xargs git checkout <SHA1_deletion>~1 --в части перед каналом перечислены все файлы, которые были удалены в фиксации; все они извлекаются из предыдущей фиксации для их восстановления.
Comments