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

如何在Git存储库中查找和恢复已删除的文件,git,file-io,git-checkout,Git,File Io,Git Checkout,假设我在Git存储库中。我删除一个文件并提交更改。我继续工作,做出更多的承诺。然后,我发现我需要恢复该文件 git log -- path/to/file 我知道我可以使用git checkout HEAD^foo.bar签出文件,但我不知道该文件是何时被删除的 找到删除给定文件名的提交的最快方法是什么 将该文件重新放入我的工作副本的最简单方法是什么 我希望我不必手动浏览我的日志,为给定的SHA签出整个项目,然后手动将该文件复制到原始项目签出中。如果你疯了,请使用。下面是要做的: git bi

假设我在Git存储库中。我删除一个文件并提交更改。我继续工作,做出更多的承诺。然后,我发现我需要恢复该文件

git log -- path/to/file
我知道我可以使用
git checkout HEAD^foo.bar
签出文件,但我不知道该文件是何时被删除的

  • 找到删除给定文件名的提交的最快方法是什么
  • 将该文件重新放入我的工作副本的最简单方法是什么
  • 我希望我不必手动浏览我的日志,为给定的SHA签出整个项目,然后手动将该文件复制到原始项目签出中。

    如果你疯了,请使用。下面是要做的:

    git bisect start
    git bisect bad
    git bisect good <some commit where you know the file existed>
    
    现在,您已处于删除它的提交位置。从这里,您可以跳回到未来,并使用撤销更改

    git bisect reset
    git revert <the offending commit>
    
  • 使用
    git log--diff filter=D--summary
    获取所有已删除文件和已删除文件的提交
  • 使用git checkout$commit~1 path/to/file.ext还原删除的文件

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

    查找影响给定路径的最后一次提交。由于文件不在头提交中,因此此提交必须已将其删除

    git rev-list -n 1 HEAD -- <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 ls-files -d | xargs git checkout --
    
    我有

  • 使用以下方法之一获取删除文件的提交的id

    • git日志--grep=*word*
    • git日志-剑
    • git日志| grep--context=5*word*
    • git log--stat | grep--context=5*word*
      #如果您不喜欢 记得吗
  • 你应该得到类似于:

  • 提交bfe68bd117e1091c96d2976c99b3bcc8310bebe7作者:Alexander 奥尔洛夫日期:2011年5月12日星期四23:44:27 +0200

    提交3ea4e3af253ac6fd1691ff6bb89c964f54802302作者:Alexander 奥尔洛夫日期:2011年5月12日星期四22:10:22 +0200

    三,。现在,使用提交id BFE68BD11E1091C96D2976C99B3BCC8310BEBE7执行以下操作:

    git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.java
    

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

    在我们的案例中,我们在提交中意外删除了文件,一些提交之后,我们意识到了错误,希望恢复所有已删除的文件,但不是那些已修改的文件

    根据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)
    
    git co$(git rev list-n1 HEAD--)~1--$(git diff--name status$(git rev list-n1 HEAD--)~1 HEAD | grep'^D'| cut-f2)
    
    要还原已删除和提交的文件:

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

    它是在Git版本1.7.5.4上测试的。

    在许多情况下,它可以与Git一起使用(grep、sed等)。我对这些工具已经很熟悉了,但对Git的了解还不够。如果我想搜索已删除的文件,我会执行以下操作:

    git log --raw | grep -B 30 $'D\t.*deleted_file.c'
    
    当我找到修订/提交时:

    git checkout <rev>^ -- path/to/refound/deleted_file.c
    
    git checkout^--path/to/refound/deleted_file.c
    
    就像其他人在我之前说过的那样

    文件现在将恢复到删除前的状态。如果你想保持它在工作树上,记得重新提交它

    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 2.23(2019年第3季度)带来了命名的(!)。
    因此,重命名此别名(如下所示)


    建议使用以下别名:

    restore-file = !git checkout $(git rev-list -n 1 HEAD -- "$1")^ -- "$1"
    
    并补充说:


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


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

    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 
    
    git show--diff filter=D--摘要--仅限名称--无提交id | xargs git checkout^--
    git show--diff filter=D--摘要--仅限名称--无提交id | xargs git重置头
    
    (请注意每个命令末尾的尾随空格。)


    这些文件已添加到.gitignore文件中,然后用
    git rm
    清除。我需要恢复这些文件,但随后将其取消分级。我有数百个文件要还原,在其他示例中手动键入每个文件的内容会太慢。

    我想还原一个刚删除但尚未提交更改的文件。如果您发现自己处于这种情况,您只需执行以下操作:

    git log --raw | grep -B 30 $'D\t.*deleted_file.c'
    

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

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

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

    管道之前的零件列出了提交中删除的所有文件;它们都是从上一次提交中签出以还原它们。

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

    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 
    
    列出该文件的所有提交

    git log -- path/to/file
    
    最后一次提交(最上面的)是删除文件的提交。因此,您需要恢复从第二次提交到最后一次提交

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

    如果您只做了更改并删除了一个文件,但没有提交它,那么现在您就放弃了更改

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

    git checkout <file_path>
    
    git签出
    
    然后,您的文件又回来了。

    git undelete path/to/file.ext
  • 将其放入您的
    .bash\u配置文件
    (或在操作时加载的其他相关文件)
    git diff --diff-filter=D --name-only <SHA1_deletion>~1 <SHA1_deletion> | xargs git checkout <SHA1_deletion>~1 --
    
    git log -- path/to/file
    
    git checkout {second to last commit} -- path/to/file
    
    git checkout -- .
    
    git checkout <file_path>
    
    git config --global alias.undelete '!sh -c "git checkout $(git rev-list -n 1 HEAD -- $1)^ -- $1" -'
    
    git undelete path/to/file.ext
    
    $ git log --diff-filter=D --summary  | grep "delete" | sort
    
    git log 
    
    git checkout <$commitid> $fileName
    
    > 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
    Author: Dave <dave@domain.com>
    Date:   Thu May 9 11:17:41 2019 -0700
    
        Revert "deleted readme"
    
        This reverts commit 2994bda49cd97ce49099953fc3f76f7d3c35d1d3.
    
    git checkout <file path with name>
    
    git log --diff-filter=D --oneline -- path/to/file | cut -f -d ' '
    
    4711174
    
    git restore --source=4711174^ path/to/file
    
    git checkout $(git ls-files --deleted)
    
    $ 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 .