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

avd*_*aag 2716 git file-io git-checkout

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

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

  1. 找到删除给定文件名的提交的最快方法是什么?
  2. 将该文件恢复到我的工作副本的最简单方法是什么?

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

CB *_*ley 3060

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

git rev-list -n 1 HEAD -- <file_path>
Run Code Online (Sandbox Code Playgroud)

然后使用caret(^)符号检查之前提交的版本:

git checkout <deleting_commit>^ -- <file_path>
Run Code Online (Sandbox Code Playgroud)

或者在一个命令中,如果$file是有问题的文件.

git checkout $(git rev-list -n 1 HEAD -- "$file")^ -- "$file"
Run Code Online (Sandbox Code Playgroud)

如果您使用zsh并启用了EXTENDED_GLOB选项,则插入符号将不起作用.你可以~1改用.

git checkout $(git rev-list -n 1 HEAD -- "$file")~1 -- "$file"
Run Code Online (Sandbox Code Playgroud)

  • 棘手的一点是使用^后缀检查提交BEFORE.谢谢. (90认同)
  • @zoras zsh在'^'上有它自己的扩展我相信,但你可以使用'~1'的替代语法:`git checkout <deletion-commit> ~1 - <file-path>`~X允许你在指定的提交之前指定X提交,因此~1是之前的提交,~2是之前的两次提交,等等 (55认同)
  • 从Windows命令行我得到一个错误.`error:pathspec <filename>与git已知的任何文件都不匹配.解决方案是使用git bash. (20认同)
  • 在windows cmd提示符下,`^`字符是转义字符!因此,在cmd上,你必须输入`^^`告诉cmd你想要一个文字^并且你不要在它之后转义别的东西.许多人发生的事情是`^`后跟一个空格.所以cmd认为你正在逃离空间 - 这只会产生一个空间角色.因此,当git获取cli参数时,它会看到`SHA1`和**而不是**`SHA1 ^`.真的很烦人.`~`不是一个转义字符,所以这就是为什么它仍然有效.(PS.如果你认为googlers会想要这个信息,请点赞此评论) (19认同)
  • 出于某种原因,这在zsh中不起作用.`±git checkout $(git rev-list -n 1 HEAD"spec/Sporkfile_example.rb")^ - "spec/Sporkfile_example.rb"zsh:找不到匹配项:b71c152d8f38dcd23ad7600a93f261a7252c59e9 ^`我切换到bash&它工作得很好虽然. (4认同)
  • @zoras你也可以用^ ^来逃避^ (2认同)
  • 请注意,您应该从您的存储库的根目录运行它,否则将无法识别文件路径.我花了几分钟直到我发现我实际上在一个子文件夹中,所以这就是为什么它不起作用. (2认同)

Rob*_*anu 834

  1. 使用git log --diff-filter=D --summary获得已删除的文件和文件删除所有提交;
  2. 使用git checkout $commit~1 path/to/file.ext恢复删除的文件.

$commit你在步骤1找到的提交的价值在哪里,例如e4cf499627

  • @Alexar` $ commit~1`表示你应该添加提交的名称.像`1d0c9ef6eb4e39488490543570c31c2ff594426c`其中`$ commit`是的. (33认同)
  • 好奇,~1指的是什么? (9认同)
  • @tommy - 波浪号规范将为您提供命名提交的第n个孙子.有关详细信息,请参阅http://book.git-scm.com/4_git_treeishes.html. (6认同)
  • 这是迄今为止最简单直观的方法.`git log - *PartOfMyFileName*`.感谢`$ commit~1` (5认同)
  • `git checkout $ commit~1 filename`语法适用于单个文件,也适用于整个目录.即:从sha 12345恢复./images中的所有已删除图像:`git checkout 12345~1 images`.谢谢你的回答! (3认同)
  • 如果您只需要检查文件内容: `git show $commit~1:$path` (2认同)
  • @BarryFruitman - 我已经更新了问题来解释“$commit”是什么。这有帮助吗? (2认同)
  • @Top-Master `$commit` 不会自动设置,它是一个占位符。`git log --diff--filter=D --summary` 返回的不仅仅是提交 SHA,并且返回的不仅仅是与您的特定文件相关的提交,因此即使我们使用它的输出,您也必须进行大量的解析。 (2认同)
  • @Dmitry,这就是 `~1` 或 `^` 的作用:在删除之前获取提交 (2认同)

Man*_*anu 314

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

git ls-files -d | xargs git checkout --
Run Code Online (Sandbox Code Playgroud)

  • 这可能是最简单的方法.它变态了`git`即使是最简单的任务也是多么困难. (20认同)
  • `ls-files`子命令很方便,但似乎不适用于使用`git rm`删除的文件,即暂停,更不用说承诺了,这就是OP所要求的. (6认同)
  • @RomainValeri,@jww 你们都是对的。“git”的实用性几乎是无与伦比的,但学习起来也极其复杂。“git”学习曲线的很大一部分是由于不一致/不直观的用户界面造成的。就我个人而言,当我学习一些困难的东西时,让我放心的一件事是看到其他(有能力的)人也在努力解决它 (4认同)
  • @RomainValeri - 现在是 2019 年。这些工具对我有用。我不是为了工具而工作。如果需要学习,那么设计就被破坏了。 (3认同)
  • 什么意思-? (2认同)

Bre*_*ett 122

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

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


Jos*_*Lee 93

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

git bisect start
git bisect bad
git bisect good <some commit where you know the file existed>
Run Code Online (Sandbox Code Playgroud)

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

git bisect run '[ -e foo.bar ]'
Run Code Online (Sandbox Code Playgroud)

现在你正处于删除它的提交中.从这里开始,您可以跳回到未来并使用git-revert撤消更改,

git bisect reset
git revert <the offending commit>
Run Code Online (Sandbox Code Playgroud)

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

git checkout HEAD^
cp foo.bar /tmp
git bisect reset
cp /tmp/foo.bar .
Run Code Online (Sandbox Code Playgroud)

  • @avdgaag `git bisect run` 告诉 Git 通过在单词 'run' 后面运行命令来自动二分,其中该命令必须为一个 `good` 版本返回 `0`(有关详细信息,请参阅 `git help bisect`)。`'[ -e foo.bar ]'` 是测试文件 `foo.bar` 是否存在的标准表达式(实现通常在文件 `/usr/bin/[` 中,它通常硬链接到 `/usr /bin/test`) 和单引号用于将所有内容作为单个命令行参数。 (3认同)
  • 你能详细说明'git bisect run'[ - e foo.bar]'` (2认同)

Von*_*onC 76

我最喜欢的别名,基于bonyiii回答(upvoted),以及我自己的回答" 将参数传递给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'
Run Code Online (Sandbox Code Playgroud)

我丢失了一个文件,错误删除了一些提交之前?
快:

git restore my_deleted_file
Run Code Online (Sandbox Code Playgroud)

危机避免了.


Robert Dailey 在评论中提出以下别名:

restore-file = !git checkout $(git rev-list -n 1 HEAD -- "$1")^ -- "$1"
Run Code Online (Sandbox Code Playgroud)

jegan 在评论中补充道:

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

git config --global alias.restore "\!git checkout \$(git rev-list -n 1 HEAD -- \"\$1\")^ -- \"\$1\"" 
Run Code Online (Sandbox Code Playgroud)

  • 这将恢复整个提交,而不仅仅是请求的文件. (7认同)
  • 这是我的别名,非常有效:`restore-file =!git checkout $(git rev-list -n 1 HEAD - "$ 1")^ - "$ 1" (5认同)
  • `扩展别名'restore'失败;'!git'不是git命令` (2认同)

wis*_*cky 52

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

列出该文件的所有提交.

git log -- path/to/file
Run Code Online (Sandbox Code Playgroud)

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

git checkout {second to last commit} -- path/to/file
Run Code Online (Sandbox Code Playgroud)

  • 这是我见过的第一个解决方案,它足够简单,下次我不必回到这里找到它。也许。 (2认同)

Fed*_*TIK 29

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

git reset HEAD some/path
git checkout -- some/path
Run Code Online (Sandbox Code Playgroud)

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


小智 25

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

git checkout -- .
Run Code Online (Sandbox Code Playgroud)

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

git checkout <file_path>
Run Code Online (Sandbox Code Playgroud)

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


Ale*_*lex 23

我有这个解决方案.

  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 Orlov日期:2011年5月12日星期四23:44:27 +0200

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

commit 3ea4e3af253ac6fd1691ff6bb89c964f54802302作者:Alexander Orlov日期:2011年5月12日星期四22:10:22 +0200

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

git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.java
Run Code Online (Sandbox Code Playgroud)

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


use*_*493 15

git checkout /path/to/deleted.file
Run Code Online (Sandbox Code Playgroud)

  • 由于删除已提交,因此无法正常工作. (7认同)

Bea*_*ith 12

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" -'
    
    Run Code Online (Sandbox Code Playgroud)
  2. 然后使用:

    git undelete path/to/file.ext
    
    Run Code Online (Sandbox Code Playgroud)

此别名首先检查以查找此文件存在的最后一次提交,然后从该文件存在的最后一次提交执行该文件路径的git检出.资源


Tho*_*s E 11

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

git log --raw | grep -B 30 $'D\t.*deleted_file.c'
Run Code Online (Sandbox Code Playgroud)

当我找到修订/提交时:

git checkout <rev>^ -- path/to/refound/deleted_file.c
Run Code Online (Sandbox Code Playgroud)

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

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


kza*_*zar 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 
Run Code Online (Sandbox Code Playgroud)

(注意每个命令末尾的尾随空格.)

这些文件已经添加到.gitignore文件中,然后用git rm清除,我需要恢复文件,然后取消它们.我有数百个要恢复的文件,为每个文件手动输入内容,因为在其他示例中,这将太慢.


Ame*_*icA 7

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

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

在此处输入图片说明

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

在此处输入图片说明

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

在此处输入图片说明

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

在此处输入图片说明

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


cb2*_*cb2 6

找到删除文件的提交:

git log --diff-filter=D --oneline -- path/to/file | cut -f -d ' '
Run Code Online (Sandbox Code Playgroud)

示例输出:

4711174
Run Code Online (Sandbox Code Playgroud)

从 Git 2.23 开始,实际上有一个restore命令。它仍然实验性的,但为了恢复您在提交中删除的内容(在这种情况下为 4711174),您可以输入:

git restore --source=4711174^ path/to/file
Run Code Online (Sandbox Code Playgroud)

注意提交 id 后面的^,因为我们想从删除文件之前的提交中恢复一些内容。

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

请参阅:git 2.23.0 的 git-restore 文档

  • 谢谢。我的剪切命令需要不同的参数。MacOS 10.13.6 和 Git 2.26 =&gt; `git log --diff-filter=D --oneline -- 路径/目标/文件 | 切 -d ' ' -f 1` (2认同)

bon*_*iii 5

在我们的例子中,我们不小心删除了一次提交中的文件,后来我们意识到了一些提交中的错误,并希望取回所有被删除的文件,但不恢复那些被修改的文件。

根据查尔斯·贝利(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)
Run Code Online (Sandbox Code Playgroud)


J. *_*ron 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
Run Code Online (Sandbox Code Playgroud)

恢复已删除的文件:

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
Run Code Online (Sandbox Code Playgroud)

  • 问题是关于在删除文件并提交更改后还原文件。该答案是关于还原仅在工作目录中删除的文件的。 (2认同)

rus*_*net 5

我有同样的问题。不知不觉中,我创建了一个悬空的提交

列出悬空提交

git fsck --lost-found

检查每个悬空的提交

git reset --hard <commit id>

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

git status 由于这个原因:

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

  • 非常感谢。你帮我恢复了数千行代码。 (2认同)

Ris*_*man 5

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

\n

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

\n

I. 如果您尚未对您的更改建立索引 (git add),您可以恢复目录内容:

\n

git restore -- path/to/folder_OR_file

\n

二. 如果删除已被索引,您应该首先重置它:

\n

git reset -- path/to/folder_OR_file

\n

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

\n

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

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


归档时间:

查看次数:

926539 次

最近记录:

6 年 前