Скажем, что я в репозитории Git. Я удаляю файл и фиксирую это изменение. Я продолжаю работать и делаю еще несколько попыток. Затем, я считаю, что мне нужно восстановить этот файл.
Я знаю, что могу проверить файл с помощью git checkout HEAD^ foo.bar
, но я действительно не знаю, когда этот файл был удален.
Я надеюсь, что мне не нужно вручную просматривать мои журналы, проверять весь проект для данной SHA, а затем вручную скопировать этот файл в мою оригинальную проверку проекта.
Найдите последний коммит, который затронул данный путь. Поскольку файл не находится в коммите 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 checkout $(git rev-list -n 1 HEAD "spec/Sporkfile_example.rb")^ -- "spec/Sporkfile_example.rb" zsh: no matches found: b71c152d8f38dcd23ad7600a93f261a7252c59e9^
Я перешел на bash, но он работал нормально.
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
сделал даже самую простую задачу.
Я пришел к этому вопросу, пытаясь восстановить только что удаленный файл, но еще не внес изменений. На всякий случай, когда вы окажетесь в этой ситуации, все, что вам нужно сделать, это следующее:
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 - в противном случае. Команда "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 .
git bisect run '[ -e foo.bar ]'
?
Мой новый любимый псевдоним, основанный на 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\""
restore-file = !git checkout $(git rev-list -n 1 HEAD -- "$1")^ -- "$1"
Если вы знаете имя файла, это простой способ с базовыми командами:
Список всех коммитов для этого файла.
git log -- path/to/file
Последний фиксатор (самый верхний) - тот, который удалил файл. Таким образом, вам нужно восстановить второе и последнее сообщение.
git checkout {second to last commit} -- path/to/file
second to last commit
комментирования!
Чтобы восстановить удаленный и завершенный файл:
git reset HEAD some/path
git checkout -- some/path
Он был протестирован на Git версии 1.7.5.4.
error: pathspec 'foo' did not match any file(s) known to git.
Я убедился, что имя файла было правильным. Git версия 2.7.0
Если вы только внесли изменения и удалили файл, но не зафиксировали его, а теперь вы расстались с вашими изменениями
git checkout -- .
но ваши удаленные файлы не вернулись, вы просто выполните следующую команду:
git checkout <file_path>
И престо, ваш файл вернулся.
У меня это решение.
Получить идентификатор комманды, где файл был удален, одним из способов ниже.
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.
git checkout /path/to/deleted.file
Во многих случаях полезно использовать 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 -- $1)^ -- $1" -'
Затем используйте:
git undelete path/to/file.ext
Этот псевдоним сначала проверяет, чтобы найти последнюю фиксацию, где был этот файл, затем выполняет git checkout этого пути к файлу от последнего коммита, где этот файл существует. источник
Поэтому мне пришлось восстановить кучу удаленных файлов из определенного коммита, и мне удалось выполнить две команды:
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, мне нужно было восстановить файлы, но затем отключить их. У меня было сотни файлов для восстановления, запись вручную для каждого файла, так как в других примерах было слишком медленно.
На самом деле, этот вопрос касается непосредственно Git
, но кто-то вроде меня работает с такими инструментами с графическим интерфейсом, как WebStorm
VCS, кроме знания команд git cli
.
Я щелкаю правой кнопкой мыши путь, содержащий удаленный файл, затем перехожу в Git
и затем нажимаю " Show History
.
Инструменты VCS показывают все изменения, и я вижу все изменения и изменения каждого из них.
Затем я выбираю коммиты, чтобы мой друг удалил файл PostAd.js
. теперь смотрите ниже:
И теперь я вижу свое желание удалить удаленный файл. Я просто дважды щелкаю по имени файла, и оно восстанавливается.
Я знаю, что мой ответ - не команды Git
но он быстрый, надежный и простой для начинающих и профессиональных разработчиков. Инструменты Webstorm VCS великолепны и идеально подходят для работы с Git
и не нуждаются ни в каком другом плагине или инструментах.
У меня такой же вопрос. Не зная этого, я создал оборванный коммит.
Список свисающих коммитов
git fsck --lost-found
Осмотрите каждый висячий коммит
git reset --hard <commit id>
Мои файлы снова появились, когда я перешел на висячий коммит.
git status
по причине:
"HEAD detached from <commit id where it detached>"
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
Если вы знаете фиксацию, которая удалила файл (ы), запустите эту команду, где <SHA1_deletion>
- это фиксация, которая удалила файл:
git diff --diff-filter=D --name-only <SHA1_deletion>~1 <SHA1_deletion> | xargs git checkout <SHA1_deletion>~1 --
Часть перед каналом перечисляет все файлы, которые были удалены в commit; все они проверяются с предыдущей фиксации, чтобы восстановить их.
В нашем случае мы случайно удалили файлы в фиксации, а некоторые зафиксировали позже, мы поняли нашу ошибку и хотели вернуть все файлы, которые были удалены, но не те, которые были изменены.
Основываясь на Чарльзе Бейли, отличный ответ здесь - мой один лайнер:
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)
Простой и precise-
Прежде всего, получите последний стабильный коммит, в котором у вас есть этот файл:
git log
Допустим, вы нашли $ commitid 1234567..., затем
git checkout <$commitid> $fileName
Это восстановит версию файла, которая была в этом коммите.
$ git log --diff-filter=D --summary | grep "delete" | sort
Если вы столкнулись с этой проблемой чаще, и вы готовы использовать инструмент Git GUI, посмотрите DeepGit и используйте Файл | Поиск.
git log --diff-filter=D -- path/to/file