首页 文章

在Git存储库中查找并恢复已删除的文件

提问于
浏览
2488

说我在Git存储库中 . 我删除了一个文件并提交了更改 . 我继续工作,并做了一些更多的提交 . 然后,我发现我需要恢复该文件 .

我知道我可以使用 git checkout HEAD^ foo.bar 签出文件,但我真的不知道该文件何时被删除 .

  • 找到删除给定文件名的提交的最快方法是什么?

  • 将该文件恢复到我的工作副本的最简单方法是什么?

我希望我不必手动浏览我的日志,检查整个项目的给定SHA,然后手动将该文件复制到我的原始项目结帐中 .

21 回答

  • 44

    在我们的例子中,我们意外地删除了提交中的文件,稍后我们意识到了我们的错误,并希望找回所有已删除但未修改的文件 .

    根据Charles Bailey的优秀答案,这是我的一个班轮:

    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)
    
  • 9
    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
    
  • 752

    如果您知道删除文件的提交,请运行此命令,其中 <SHA1_deletion> 是删除文件的提交:

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

    管道前面的部分列出了提交中删除的所有文件;它们都是从上一次提交结账以恢复它们 .

  • 21

    git取消删除路径/到/ file.ext

    • 将它放在 .bash_profile (或打开命令shell时加载的其他相关文件)中:
    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 . source

  • 14
    $ git log --diff-filter=D --summary  | grep "delete" | sort
    
  • 1
    git checkout /path/to/deleted.file
    
  • 6

    查找影响给定路径的最后一次提交 . 由于该文件不在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"
    
  • 4

    要还原文件夹中的所有已删除文件,请输入以下命令 .

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

    如果您知道文件名,这是使用基本命令的简单方法:

    列出该文件的所有提交 .

    git log -- path/to/file
    

    最后一次提交(最顶层)是删除文件的提交 . 所以你需要恢复倒数第二次提交 .

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

    在许多情况下,将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
    

    就像其他人在我面前所说的那样 .

    该文件现在将恢复到删除之前的状态 . 如果要保留它,请记住将其重新提交到工作树 .

  • 305

    我最喜欢的别名,基于bonyiiianswer(upvoted),以及我自己对“Pass an argument to a Git alias command”的回答:

    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
    

    危机避免了 .


    Robert Dailey建议in the comments以下别名:

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

    并且jegan添加in the comments

    为了从命令行设置别名,我使用了以下命令:

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

    实际上,这个问题直接关于 Git ,但是像我这样的人使用像 WebStorm VCS这样的GUI工具,除了知道git cli 命令 .

    我右键单击包含已删除文件的路径,然后转到 Git 然后单击 Show History .

    VCS工具显示所有修订版本,我可以看到每个版本的所有提交和更改 .

    然后我选择我的朋友删除 PostAd.js 文件的提交 . 现在看下面:

    现在,我可以看到我的愿望删除文件 . 我只需双击文件名即可恢复 .

    我知道我的答案不是 Git 命令,但它对于初学者和专业开发人员来说快速,可靠且容易 . Webstorm VCS工具非常棒,非常适合使用 Git ,并且不需要任何其他插件或工具 .

  • 2820

    如果你疯了,请使用git-bisect . 这是做什么的:

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

    现在是时候运行自动化测试了 . 如果存在 foo.bar ,则shell命令 '[ -e foo.bar ]' 将返回0,否则返回1 . git-bisect 的"run"命令将使用二进制搜索自动查找测试失败的第一个提交 . 它从给定范围的中间开始(从好到坏),并根据指定测试的结果将其减半 .

    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 .
    
  • 4

    要还原已删除和已提交的文件:

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

    它在Git 1.7.5.4版本上进行了测试 .

  • -1

    我有this solution .

    • 获取提交的ID使用以下方法之一删除文件的位置 .

    • git log --grep=*word*

    • git log -Sword

    • git log | grep --context=5 *word*

    • git log --stat | grep --context=5 *word* #推荐,如果你几乎没有记住的话

    • 你应该得到类似的东西:

    commit bfe68bd117e1091c96d2976c99b3bcc8310bebe7作者:Alexander Orlov日期:2011年5月12日星期四23:44:27 0200取代已弃用的GWT课程

    • gwtI18nKeySync.sh,一个过时的(?,由Maven目标取代)I18n生成脚本
      commit 3ea4e3af253ac6fd1691ff6bb89c964f54802302作者:Alexander Orlov日期:2011年5月12日星期四22:10:22 0200

    3.现在使用提交ID bfe68bd117e1091c96d2976c99b3bcc8310bebe7执行:

    git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.java
    

    由于提交ID引用了已经删除文件的提交,因此您需要在bfe68b之前引用提交,您可以通过附加 ^1 来执行提交 . 这意味着:在bfe68b之前给我提交 .

  • 23

    所以我不得不从特定的提交中恢复一堆已删除的文件,并使用两个命令进行管理:

    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清除,我需要恢复文件,然后取消它们 . 我有几百个要恢复的文件,为每个文件手动输入内容,因为在其他示例中,这将太慢 .

  • 108

    我来到这个问题寻找恢复我刚删除的文件,但我还没有提交更改 . 如果您发现自己处于这种情况,您需要做的就是以下内容:

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

  • 64
    • 使用 git log --diff-filter=D --summary 获取已删除文件和删除文件的所有提交;

    • 使用 git checkout $commit~1 filename 恢复已删除的文件 .

    其中 $commit 是您在步骤1中找到的提交值,例如 e4cf499627

  • 28

    简单而精确 -

    首先,获取最新的稳定提交,其中您拥有该文件 -

    git log
    

    假设您找到$ commitid 1234567 ...,然后

    git checkout <$commitid> $fileName
    

    这将恢复该提交中的文件版本 .

  • 10

    如果您只进行了更改并删除了一个文件,但没有提交,那么现在您就分手了

    git checkout -- .
    

    但是您删除的文件没有返回,您只需执行以下命令:

    git checkout <file_path>
    

    而且,你的档案又回来了 .

  • 1

    我有同样的问题 . 在不知情的情况下,我创建了一个 dangling commit .

    列出悬空提交

    git fsck --lost-found

    检查每个悬挂的提交

    git reset --hard <commit id>

    当我转向悬空提交时,我的文件重新出现 .

    git status 原因如下:

    “HEAD detached from <commit id where it detached>”

相关问题