git - Git repo 恢复已删除的文件

  显示原文与译文双语对照的内容

假设我在一个Git仓库中。 删除文件并提交更改。 我继续工作并做一些提交。 然后,我发现我需要恢复那个文件。

我知道我可以用 git checkout HEAD^ foo.bar ,但我不知道该文件什么时候被删除。

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

我希望不需要手动浏览我的日志,为给定的SHA签出整个项目,然后手动将该文件复制到我原来的项目签出。

时间:

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

  1. 使用 git log --diff-filter=D --summary 获取所有已经删除的文件和删除的文件;
  2. 使用 git checkout $commit~1 filename 恢复已经删除的文件。

如果你疯了,使用 git-bisect 。 以下是要做的:


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

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


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. 

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

已经避免危机。


Dailey 。在注释中建议 ,如下别名:


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

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

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

我得到了这个解决方案

  1. 获取使用以下方法删除文件的提交的标识。

    • git log --grep=*word*
    • git log -Sword
    • git log | grep --context=5 *word*
    • git log --stat | grep --context=5 *word* # 推荐如果你几乎不记得任何东西
  2. 你应该得到类似:

提交bfe68bd117e1091c96d2976c99b3bcc8310bebe7作者:亚历山大Orlov日期: 星期四 12 23: 44: 27 2011 +0200


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

提交 3 ea4e3af253ac6fd1691ff6bb89c964f54802302作者:亚历山大Orlov日期: 星期四 12 22: 10: 22 2011 +0200

使用的提交 id bfe68bd117e1091c96d2976c99b3bcc8310bebe7 do, 3 。now:


git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.java

由于提交标识引用了已经删除文件的提交,你需要在bfe68b之前引用提交,你可以通过附加 ^1 来完成提交。 这意味着:在bfe68b之前提交提交。

在很多情况下,使用 coreutils(grep,sed,etc.) 和git是很有用的。 我已经很好地了解了这些工具,但是git不如。 如果要搜索已经删除的文件,我将执行以下操作:


git log --raw | grep -B 30 $'Dt.*deleted_file.c'

当我找到修订/提交时:


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

就像其他人前面所说的。

文件现在将恢复到删除之前的状态。 如果你想把它保存在工作树上,记得把它放在工作树上。

...