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

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

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

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

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

+2674
источник поделиться
25 ответов

Найдите последний коммит, который затронул данный путь. Поскольку файл не находится в коммите 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"
+3016
источник
  1. Используйте git log --diff-filter=D --summary чтобы получить все коммиты, которые удалили файлы и файлы удалены;
  2. Используйте git checkout $commit~1 path/to/file.ext для восстановления удаленного файла.

Где $commit - это значение коммита, которое вы нашли на шаге 1, например, e4cf499627

+825
источник
другие ответы

Связанные вопросы


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

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

git ls-files -d | xargs git checkout --
+311
источник

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

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

+120
источник

Если вы безумны, используйте 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 - в противном случае. Команда "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 .
+89
источник

Мой новый любимый псевдоним, основанный на bonyiii answer (upvoted), и мой собственный ответ about "Передайте аргумент команде 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\"" 
+72
источник

Если вы знаете имя файла, это простой способ с базовыми командами:

Список всех коммитов для этого файла.

git log -- path/to/file

Последний фиксатор (самый верхний) - тот, который удалил файл. Таким образом, вам нужно восстановить второе и последнее сообщение.

git checkout {second to last commit} -- path/to/file
+49
источник

Чтобы восстановить удаленный и завершенный файл:

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

Он был протестирован на Git версии 1.7.5.4.

+29
источник

Если вы только внесли изменения и удалили файл, но не зафиксировали его, а теперь вы расстались с вашими изменениями

git checkout -- .

но ваши удаленные файлы не вернулись, вы просто выполните следующую команду:

git checkout <file_path>

И престо, ваш файл вернулся.

+25
источник

У меня это решение.

  • Получить идентификатор комманды, где файл был удален, одним из способов ниже.

    • git log --grep=*word*
    • git log -Sword
    • git log | grep --context=5 *word*
    • git log --stat | grep --context=5 *word* # рекомендуется, если вы вряд ли запомнить что-нибудь
  • Вы должны получить что-то вроде:

commit bfe68bd117e1091c96d2976c99b3bcc8310bebe7 Автор: Александр Орлов Дата: Чт май 12 23:44:27 2011 +0200

replaced deprecated GWT class
- gwtI18nKeySync.sh, an outdated (?, replaced by a Maven goal) I18n generation script

commit 3ea4e3af253ac6fd1691ff6bb89c964f54802302 Автор: Alexander Орлов Дата: Чт май 12 22:10:22 2011 +0200

3. Теперь, используя идентификатор commit bfe68bd117e1091c96d2976c99b3bcc8310bebe7 do:

git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.java

Поскольку идентификатор commit ссылается на фиксацию, где файл уже был удален, вам нужно ссылаться на commit непосредственно перед bfe68b, который вы можете сделать, добавив ^1. Это означает: дать мне фиксацию непосредственно перед bfe68b.

+23
источник
git checkout /path/to/deleted.file
+15
источник

git undelete path/to/file.ext

  • Поместите это в свой .bash_profile (или другой соответствующий файл, который загружается при открытии командной оболочки):

    git config --global alias.undelete '!sh -c "git checkout $(git rev-list -n 1 HEAD -- $1)^ -- $1" -'
    
  • Затем используйте:

    git undelete path/to/file.ext
    

Этот псевдоним сначала проверяет, чтобы найти последнюю фиксацию, где был этот файл, затем выполняет git checkout этого пути к файлу от последнего коммита, где этот файл существует. источник

+12
источник

Во многих случаях полезно использовать 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

Точно так же, как другие заявили передо мной.

Теперь файл будет восстановлен до состояния, которое было перед удалением. Не забудьте повторно зафиксировать его на рабочем дереве, если вы хотите его сохранить.

+11
источник

Поэтому мне пришлось восстановить кучу удаленных файлов из определенного коммита, и мне удалось выполнить две команды:

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, мне нужно было восстановить файлы, но затем отключить их. У меня было сотни файлов для восстановления, запись вручную для каждого файла, так как в других примерах было слишком медленно.

+7
источник

На самом деле, этот вопрос касается непосредственно Git, но кто-то вроде меня работает с такими инструментами с графическим интерфейсом, как WebStorm VCS, кроме знания команд git cli.

Я щелкаю правой кнопкой мыши путь, содержащий удаленный файл, затем перехожу в Git и затем нажимаю " Show History.

enter image description here

Инструменты VCS показывают все изменения, и я вижу все изменения и изменения каждого из них.

enter image description here

Затем я выбираю коммиты, чтобы мой друг удалил файл PostAd.js. теперь смотрите ниже:

enter image description here

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

enter image description here

Я знаю, что мой ответ - не команды Git но он быстрый, надежный и простой для начинающих и профессиональных разработчиков. Инструменты Webstorm VCS великолепны и идеально подходят для работы с Git и не нуждаются ни в каком другом плагине или инструментах.

+6
источник
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
+5
источник

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

Список свисающих коммитов

git fsck --lost-found

Осмотрите каждый висячий коммит

git reset --hard <commit id>

Мои файлы снова появились, когда я перешел на висячий коммит.

git status по причине:

"HEAD detached from <commit id where it detached>"

+5
источник

В нашем случае мы случайно удалили файлы в фиксации, а некоторые зафиксировали позже, мы поняли нашу ошибку и хотели вернуть все файлы, которые были удалены, но не те, которые были изменены.

Основываясь на Чарльзе Бейли, отличный ответ здесь - мой один лайнер:

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)
+4
источник

Если вы знаете фиксацию, которая удалила файл (ы), запустите эту команду, где <SHA1_deletion> - это фиксация, которая удалила файл:

git diff --diff-filter=D --name-only <SHA1_deletion>~1 <SHA1_deletion> | xargs git checkout <SHA1_deletion>~1 --

Часть перед каналом перечисляет все файлы, которые были удалены в commit; все они проверяются с предыдущей фиксации, чтобы восстановить их.

+4
источник

Простой и precise-

Прежде всего, получите последний стабильный коммит, в котором у вас есть этот файл:

git log 

Допустим, вы нашли $ commitid 1234567..., затем

git checkout <$commitid> $fileName

Это восстановит версию файла, которая была в этом коммите.

+2
источник

Найдите коммит, который удалил ваш файл:

git log --diff-filter=D --oneline -- path/to/file | cut -f -d ' '

Пример вывода:

4711174

Начиная с Git 2.23, на самом деле есть команда restore. Он все еще экспериментальный, но чтобы восстановить что-то, что вы удалили в коммите (в данном случае 4711174), вы можете набрать:

git restore --source=4711174^ path/to/file

Обратите внимание на ^ после идентификатора коммита, поскольку мы хотим восстановить что-то из коммита до того, который удалил файл.

Аргумент --source сообщает команде restore, где искать файл для восстановления, и это может быть любой коммит и даже индекс.

Смотрите: git-restore doc для git 2.23.0

+2
источник

Я знаю, что это старая ветка, но вы всегда можете git revert ваш коммит, который удалил файл. (Это предполагает, что удаление было единственным изменением в коммите.)

> git log 
commit 2994bda49cd97ce49099953fc3f76f7d3c35d1d3
Author: Dave <dave@domain.com>
Date:   Thu May 9 11:11:06 2019 -0700

    deleted readme.md

И если вы продолжили работу и позже поняли, что не хотите фиксировать этот коммит удаления, вы можете отменить его, используя.

> git revert 2994bd

Теперь git log показывает:

> git log
Author: Dave <dave@domain.com>
Date:   Thu May 9 11:17:41 2019 -0700

    Revert "deleted readme"

    This reverts commit 2994bda49cd97ce49099953fc3f76f7d3c35d1d3.

И readme.md был восстановлен в хранилище.

0
источник

Если вы столкнулись с этой проблемой чаще, и вы готовы использовать инструмент Git GUI, посмотрите DeepGit и используйте Файл | Поиск.

-1
источник
$ git log --diff-filter=D --summary  | grep "delete" | sort
-1
источник

У меня также есть эта проблема, используя приведенный ниже код, чтобы получить предыдущий файл в локальный каталог

git checkout <file path with name>

пример ниже работает для меня

git checkout resources/views/usaSchools.blade.php

Спасибо

-1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос