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

时间:2009-06-04 22:40:34

标签: git file-io git-checkout

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

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

  1. 找到删除给定文件名的提交的最快方法是什么?
  2. 将该文件恢复到我的工作副本的最简单方法是什么?
  3. 我希望我不必手动浏览我的日志,检查整个项目的给定SHA,然后手动将该文件复制到我的原始项目结帐中。

29 个答案:

答案 0 :(得分:2957)

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

答案 1 :(得分:806)

  1. 使用git log --diff-filter=D --summary获取已删除文件和删除文件的所有提交;
  2. 使用git checkout $commit~1 path/to/file.ext恢复已删除的文件。
  3. 其中$commit是您在步骤1中找到的提交值,例如e4cf499627

答案 2 :(得分:307)

要恢复文件夹中所有已删除的文件,请输入以下命令。

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

答案 3 :(得分:118)

我来到这个问题,希望恢复我刚删除的文件,但我还没有提交更改。如果你发现自己处于这种情况,你需要做的就是:

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

答案 4 :(得分:89)

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

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

现在是时候运行自动化测试了。如果存在'[ -e foo.bar ]',则shell命令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 .

答案 5 :(得分:71)

我最喜欢的别名,基于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\"" 

答案 6 :(得分:45)

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

列出该文件的所有提交。

git log -- path/to/file

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

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

答案 7 :(得分:29)

恢复已删除并已提交的文件:

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

在Git 1.7.5.4版本上进行了测试。

答案 8 :(得分:24)

如果您只进行了更改并删除了某个文件,但未提交该文件,那么现在您已经解决了这些更改

git checkout -- .

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

git checkout <file_path>

然后,你的档案又回来了。

答案 9 :(得分:23)

我有this solution

  1. 使用以下方法之一获取文件被删除的提交ID。

    • git log --grep=*word*
    • git log -Sword
    • git log | grep --context=5 *word*
    • git log --stat | grep --context=5 *word*#推荐如果你很难 记住任何事情
  2. 你应该得到类似的东西:

  3.   

    commit bfe68bd117e1091c96d2976c99b3bcc8310bebe7作者:亚历山大   Orlov日期:2011年5月12日星期四23:44:27   0200

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

    commit 3ea4e3af253ac6fd1691ff6bb89c964f54802302作者:亚历山大   Orlov日期:2011年5月12日星期四22:10:22   0200

    3 。现在使用提交ID bfe68bd117e1091c96d2976c99b3bcc8310bebe7做:

    git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.java
    

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

答案 10 :(得分:15)

git checkout /path/to/deleted.file

答案 11 :(得分:11)

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

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

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

答案 12 :(得分:10)

git undelete path/to/file.ext

  1. 将它放在.bash_profile(或打开命令shell时加载的其他相关文件)中:

    git config --global alias.undelete '!sh -c "git checkout $(git rev-list -n 1 HEAD -- $1)^ -- $1" -'
    
  2. 然后使用:

    git undelete path/to/file.ext
    
  3. 此别名首先检查以查找此文件存在的最后一次提交,然后从该文件存在的最后一次提交执行该文件路径的git checkout。 source

答案 13 :(得分:7)

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

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

答案 14 :(得分:5)

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

答案 15 :(得分:5)

我有同样的问题。在不知情的情况下,我创建了一个 悬空提交

列出悬空提交

git fsck --lost-found

检查每个悬空提交

git reset --hard <commit id>

当我转移到悬空提交时,我的文件重新出现。

git status原因是:

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

答案 16 :(得分:5)

实际上,这个问题直接与Git有关,但是像我这样的人除了了解git WebStorm命令以外,还使用cli VCS这样的GUI工具。

我右键单击包含已删除文件的路径,然后转到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一起使用,不需要任何其他插件或工具。

答案 17 :(得分:4)

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

根据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)

答案 18 :(得分:4)

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

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

管道前面的部分列出了提交中删除的所有文件;它们都是从之前的提交中检出来恢复它们。

答案 19 :(得分:3)

找到删除文件的提交:

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

请注意提交ID后的 ^ ,因为我们希望从删除文件的之前还原提交中的某些内容。

--source参数告诉restore命令在哪里寻找要还原的文件,它可以是任何提交甚至是索引。

请参阅:git-restore doc for git 2.23.0

答案 20 :(得分:2)

简单而精确-

首先,获得最新的稳定提交,其中--p

git log 

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

git checkout <$commitid> $fileName

这将还原该提交中的文件版本。

答案 21 :(得分:2)

为获得最佳效果,请尝试一下。


首先,找到删除文件的提交的提交ID。 它将为您提供有关已删除文件的提交的摘要。

git log --diff-filter = D --summary

git checkout 84sdhfddbdddf〜1

注意:84sdhfddbddd是您的commit id

通过此操作,您可以轻松恢复所有已删除的文件。

答案 22 :(得分:1)

加分点:以下方法确实适用于文件/文件夹甚至从垃圾箱或回收站中删除的情况。

文件/文件夹已从工作树中删除但尚未提交:

我。如果您还没有索引 (git add) 您的更改,您可以恢复目录的内容:

git restore -- path/to/folder_OR_file

二。如果删除已编入索引,您应该先重置它:

git reset -- path/to/folder_OR_file

然后执行,git restore path/to/folder_OR_file

文件/文件夹在过去的某些提交中被删除:

  1. 使用 git log --diff-filter=D --summary 获取删除文件/文件夹的提交的详细信息;
  2. 使用 git checkout $commit~1 path/to/folder_OR_file 恢复已删除的文件/文件夹。 $commit 是您在第 1 步找到的提交的 sha 值,例如c7578994

答案 23 :(得分:0)

使用下面的代码将以前的文件检索到本地目录时,我也遇到了这个问题

git checkout <file path with name>

下面为我工作的示例

git checkout resources/views/usaSchools.blade.php

谢谢

答案 24 :(得分:0)

为了使用git恢复所有已删除的文件,您还可以执行以下操作:git checkout $(git ls-files --deleted)

git ls-files --deleted在参数中列出所有已删除文件,而git checkout $(git command)还原文件列表。

答案 25 :(得分:0)

我知道这是一个旧线程,但是您始终可以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已恢复到存储库中。

答案 26 :(得分:0)

您可以检出已删除的文件:

git checkout

输出

D       index.html

要恢复它:

git restore index.html

如果您删除了多个文件并且需要恢复所有使用:

git restore .

查看 Gif 图像 restore files by git

答案 27 :(得分:0)

$ git log --diff-filter=D --summary  | grep "delete" | sort

答案 28 :(得分:-1)

如果尚未提交删除操作,则以下命令将在工作树中恢复已删除的文件。

$ git checkout -- <file>

您可以使用以下命令获取工作树中所有已删除文件的列表。

$ git ls-files --deleted

如果删除已提交,请在发生删除的地方找到该提交,然后从该提交中恢复文件。

$ git rev-list -n 1 HEAD -- <file>
$ git checkout <commit>^ -- <file>

如果您正在寻找要恢复的文件的路径,则以下命令将显示所有已删除文件的摘要。

$ git log --diff-filter=D --summary