Найти и восстановить удаленный файл в репозитории Git
Скажем, я в Git-хранилище. Я удаляю файл и фиксирую это изменение. Я продолжаю работать и делаю еще коммиты. Затем я обнаружил, что мне нужно восстановить этот файл.
Я знаю, что могу оформить заказ, используя файл git checkout HEAD^ foo.bar
, но я не знаю, когда этот файл был удален.
- Какой самый быстрый способ найти коммит, который удалил данное имя файла?
- Что было бы самым простым способом вернуть этот файл в мою рабочую копию?
Я надеюсь, что мне не придется вручную просматривать мои журналы, извлекать весь проект для данного SHA, а затем вручную копировать этот файл в исходную проверку моего проекта.
31 ответ
Найдите последний коммит, который затронул данный путь. Поскольку файл не находится в коммите 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"
- использование
git log --diff-filter=D --summary
получить все коммиты, которые удалили файлы и файлы удалены; - использование
git checkout $commit~1 path/to/file.ext
восстановить удаленный файл.
куда $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, если 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 .
Мой новый любимый псевдоним, основанный на ответе bonyiii (upvoted) и моем собственном ответе о " Передать аргумент команде псевдонима Git ":
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
Кризис предотвращен.
void.pointer предлагает в комментариях следующий псевдоним:
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\""
Если вы знаете имя файла, это простой способ с основными командами:
Перечислите все коммиты для этого файла.
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 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 Автор: Александр Орлов Дата: Чт, 12 мая 22:10:22 2011 +0200
3 Теперь, используя идентификатор фиксации bfe68bd117e1091c96d2976c99b3bcc8310bebe7, сделайте:
git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.java
Поскольку идентификатор коммита ссылается на коммит, где файл уже был удален, вам нужно ссылаться на коммит непосредственно перед bfe68b, что можно сделать, добавив ^1
, Это значит: дай мне коммит как раз перед bfe68b.
Если вы только внесли изменения и удалили файл, но не зафиксировали его, а теперь вы расстались со своими изменениями
git checkout -- .
но ваши удаленные файлы не вернулись, вы просто выполните следующую команду:
git checkout <file_path>
И до того, ваш файл вернулся.
На самом деле, этот вопрос непосредственно о Git
, но кто-то вроде меня работает с такими инструментами GUI, как WebStorm
VCS кроме знания о мерзавце cli
команды.
Я щелкаю правой кнопкой мыши на пути, который содержит удаленный файл, а затем перейти к Git
а затем нажмите на Show History
,
Инструменты VCS показывают все изменения, и я вижу все изменения и изменения каждого из них.
Затем я выбираю коммиты, которые мой друг удаляет PostAd.js
файл. теперь смотрите ниже:
И теперь я вижу свое желание удалить удаленный файл. Я просто дважды щелкаю по имени файла, и оно восстанавливается.
Я знаю, что мой ответ не Git
Команды, но это быстро, надежно и легко для начинающих и профессиональных разработчиков. Инструменты Webstorm VCS великолепны и идеально подходят для работы с Git
и не нуждается ни в каком другом плагине или инструментах.
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 извлечение пути этого файла из того последнего коммита, где этот файл существовал. источник
Во многих случаях может быть полезно использовать 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 fsck --lost-found
Осмотрите каждый висячий коммит
git reset --hard <commit id>
Мои файлы снова появились, когда я перешел на висячий коммит.
git status
по причине:
“HEAD detached from <commit id where it detached>”
Найдите фиксацию, которая удалила ваш файл:
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 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, мне нужно было восстановить файлы, но затем удалить их. Мне нужно было восстановить сотни файлов, набирать вещи вручную для каждого файла, как в других примерах, было слишком медленно.
Плюс: приведенные ниже методы хорошо работают в сценарии, когда файлы / папки были удалены даже из корзины или корзины.
Файлы / папки удаляются из рабочего дерева, но еще не зафиксированы:
I. Если вы еще не проиндексировали (git add) свои изменения, вы можете вернуть содержимое каталога:
git restore -- path/to/folder_OR_file
II. Если удаление уже проиндексировано, вы должны сначала сбросить его:
git reset -- path/to/folder_OR_file
затем выполнить,
git restore path/to/folder_OR_file
Файлы / папки удаляются в некоторых коммитах в прошлом:
- Использовать
git log --diff-filter=D --summary
чтобы получить подробную информацию о коммитах, в которых были удалены файлы / папки; - Использовать
git checkout $commit~1 path/to/folder_OR_file
для восстановления удаленных файлов / папки. Где$commit
- значение sha фиксации, найденной на шаге 1, например c7578994
В нашем случае мы случайно удалили файлы в коммите, а некоторые из коммитов позже осознали свою ошибку и хотели получить обратно все файлы, которые были удалены, но не те, которые были изменены.
Основываясь на превосходном ответе Чарльза Бейли, вот мой единственный вкладыш:
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)
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 log --diff-filter=D --сводка
git checkout 84sdhfddbdddf~1
Примечание: 84sdhfddbddd
твой commit id
Благодаря этому вы можете легко восстановить все удаленные файлы.
Если вы знаете коммит, который удалил файл (ы), выполните эту команду где <SHA1_deletion>
это коммит, который удалил файл:
git diff --diff-filter=D --name-only <SHA1_deletion>~1 <SHA1_deletion> | xargs git checkout <SHA1_deletion>~1 --
Часть перед конвейером перечисляет все файлы, которые были удалены в коммите; они все извлечены из предыдущего коммита, чтобы восстановить их.
Это самое простое решение, которое я нашел, если вы хотите просто восстановить тот же файл в мастере:
git checkout master -- path/to/File.java
Простой и точный
Прежде всего, получите последний стабильный коммит, в котором у вас есть этот файл:
git log
Допустим, вы нашли $commitid 1234567..., затем
git checkout <$commitid> $fileName
Это восстановит версию файла, которая была в этом коммите.
Ты всегда мог 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
восстановлен в репозиторий.
У меня также есть эта проблема с использованием приведенного ниже кода для извлечения предыдущего файла в локальный каталог:
git checkout <file path with name>
Приведенный ниже пример работает для меня:
git checkout resources/views/usaSchools.blade.php
Если удаление не было зафиксировано, приведенная ниже команда восстановит удаленный файл в рабочем дереве.
$ git checkout -- <file>
Вы можете получить список всех удаленных файлов в рабочем дереве, используя команду ниже.
$ git ls-files --deleted
Если удаление было зафиксировано, найдите фиксацию, в которой это произошло, затем восстановите файл из этой фиксации.
$ git rev-list -n 1 HEAD -- <file>
$ git checkout <commit>^ -- <file>
Если вы ищете путь к файлу для восстановления, следующая команда отобразит сводку всех удаленных файлов.
$ git log --diff-filter=D --summary
Вы можете проверить удаленные файлы:
git checkout
Выход
D index.html
Чтобы его восстановить:
git restore index.html
Если вы удалили несколько файлов и вам нужно восстановить все использование:
git restore .
Два способа показать удаленные файлы
Первый способ
git checkout
второй способ
git status -s |grep d
grep d, чтобы показать только удаленные файлы
Чтобы восстановить его, напишите эту команду
git checkout .
Обратите внимание, что предыдущая команда восстановит все удаленные файлы.
Или восстановите по имени файла
git checkout -- filename
Чтобы восстановить все удаленные файлы с помощью Git, вы также можете:
git checkout $(git ls-files --deleted)
куда git ls-files --deleted
перечисляет все удаленные файлы и git checkout $(git command)
восстанавливает список файлов в параметре.