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

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

我知道我可以使用git checkout <commit> -- filename.txt签出文件,但我不知道该文件何时被删除。

  1. 如何找到删除给定文件名的提交?
  2. 如何将该文件恢复回我的工作副本?
1099867 次浏览

如果你疯了,使用#0。这是要做的:

git bisect startgit bisect badgit 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 ]'

现在你在删除它的提交处。从这里,你可以跳回未来并使用#0撤消更改,

git bisect resetgit revert <the offending commit>

或者您可以返回一次提交并手动检查损坏情况:

git checkout HEAD^cp foo.bar /tmpgit bisect resetcp /tmp/foo.bar .
  1. 获取所有已删除文件的提交,以及已删除的文件:

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

    记下所需的提交哈希,例如e4e6d4d5e5c59c69f3bd7be2

  2. 将删除的文件从之前的一次提交(~1)恢复到上面确定的提交(e4e6d4d5e5c59c69f3bd7be2):

    git checkout e4e6d4d5e5c59c69f3bd7be2~1 path/to/file.ext

    注意~1

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

我有这个解决方案

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

    • git log --grep=*word*
    • git log -Sword
    • git log | grep --context=5 *word*
    • git log --stat | grep --context=5 *word*#推荐如果你不喜欢记住任何事情
  2. 你应该得到这样的东西:

提交bfe68bd117e1091c96d2976c99b3bcc8310bebe7作者:Alexander时间: 2011年5月12日星期四23:44:27+0200

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

提交3ea4e3af253ac6fd1691ff6bb89c964f54802302作者:亚历山大时间:2011年5月12日星期四22:10:22+0200

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

git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.java

由于提交ID引用了文件已经删除的提交,因此您需要在bfe之前引用提交68b您可以通过附加^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 reset HEAD some/pathgit checkout -- some/path

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

在许多情况下,将coreutils(grep、ses等)与Git结合使用可能很有用。我已经非常了解这些工具,但Git不太了解。如果我想搜索已删除的文件,我会执行以下操作:

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

当我找到修订/提交时:

git checkout <rev>^ -- path/to/refound/deleted_file.c

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

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

user@bsd:~/work/git$ rm slides.texuser@bsd:~/work/git$ git pullAlready up-to-date.user@bsd:~/work/git$ ls slides.texls: slides.tex: No such file or directory

恢复已删除的文件:

user@bsd:~/work/git$ git checkoutD       .slides.tex.swpD       slides.texuser@bsd:~/work/git$ git checkout slides.texuser@bsd:~/work/git$ ls slides.texslides.tex

我最喜欢的新别名,基于bonyiii回答(赞成),以及我自己对“将参数传递给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

危机避免了。

警告,Git 2.23(2019年第三季度)中的实验命令名为#0(!)。
所以重命名这个别名(如下所示)。


罗伯特戴利建议在评论使用以下别名:

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 checkout /path/to/deleted.file

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

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清除。我需要恢复这些文件,但随后取消了它们。我有数百个文件要恢复,像其他示例一样为每个文件手动输入内容太慢了。

如果您删除了最新HEAD提交中存在的文件,您可以使用以下方法恢复它:

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

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

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 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. Then use:

    git undelete path/to/file.ext

This alias first checks to find the last commit where this file existed, and then does a Git checkout of that file path from that last commit where this file existed. Source.

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

列出悬空提交

git fsck --lost-found

检查每个悬空提交

git reset --hard <commit id>

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

git status原因:

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

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

简单而精确

首先,通过以下方式获取具有该文件的最新稳定提交-

git log

假设你找到1234567美元,然后

git checkout <$commitid> $fileName

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

实际上,这个问题直接与Git有关,但像我这样的人使用WebStormVCS等GUI工具,而不是了解Git CLI命令。

我右键单击包含已删除文件的路径,然后转到Git,然后单击显示历史

在此处输入图片描述

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

在此处输入图片描述

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

在此处输入图片描述

现在,我可以看到我想要删除的文件。我只需双击文件名,它就会恢复。

在此处输入图片描述

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

您总是可以git revert删除文件的提交。(这假设删除是提交中的唯一更改。

> git logcommit 2994bda49cd97ce49099953fc3f76f7d3c35d1d3Author: Dave <dave@domain.com>Date:   Thu May 9 11:11:06 2019 -0700
deleted readme.md

如果您继续工作,并且后来意识到您不想提交该删除提交,您可以使用以下命令恢复它:

> git revert 2994bd

现在git log显示:

> git logAuthor: 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 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 2.23.0的git恢复文档

为了使用Git恢复所有已删除的文件,您还可以执行:

git checkout $(git ls-files --deleted)

其中git ls-files --deleted列出所有已删除的文件,git checkout $(git command)在参数中恢复文件列表。

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

$ git checkout -- <file>

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

$ git ls-files --deleted

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

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

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

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

为了找到最好的方法,试试看。


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

git log--diff-filter=D##########删除日志

git检查84sdhfddbdddf~1

注意:84sdhfddbddd是你的commit id

您可以轻松恢复所有已删除的文件。

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

git checkout

产出

D       index.html

要恢复它:

git restore index.html

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

git restore .

查看Gif图像通过git恢复文件

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

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

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

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

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

如果您只想在master中恢复相同的文件,这是我找到的最简单的解决方案:

git checkout master -- path/to/File.java