78

我添加了一个新文件F1并对另一个文件 F2 进行了更改,但随后做了 agit reset --hard HEAD^并且我丢失了对文件的所有更改。

有什么办法可以让他们找回来吗

我确实在这里查看了一个相关问题:如何撤消 git reset --hard HEAD~1? 但是,该问题假定该人已经完成了 Git 提交。

4

5 回答 5

151

您可以(通过一些工作)在最后一个“git add <file> ”恢复文件状态。您可以使用

$ git fsck --cache --no-reflogs --lost-found --dangling HEAD

然后检查 '.git/lost-found/other' 目录中的文件。

请阅读git fsck 手册页。

于 2009-07-10T13:10:34.770 回答
37

(我假设丢失的文件不是任何提交的一部分。否则,git log --all -g --diff-filter=D --stat是你的朋友。)

  1. git获取知道文件名的不可达文件列表:

    git fsck --unreachable --no-reflogs --no-cache HEAD | fgrep " tree " \
    | cut -d " " -f3 | xargs -r -n1 git ls-tree \
    | fgrep " blob " | cut -d " " -f 3- | sort -k2 -u
    
  2. 如果你看到一些有趣的东西,git cat-file blob SHA-1-of-interesting-file会将文件输出到标准输出。(例如git cat-file blob b8f0bdf56 > recovered-logo.png:)

不幸的是,如果丢失的文件不是任何提交的一部分,git 没有时间戳,因此,您无法打印按时间排序的各种版本的文件。

如果丢失的文件从未被暂存(git stagegit add)或隐藏(git stash),那么你很不走运,因为据 git 所知,该文件从未存在过。(您仍然可以尝试git fsck --no-reflogs --lost-found在目录.git/lost-found/other中查看是否有任何值得保留的东西,以防 git 确实有您丢失的文件的副本,因为一些幸运的意外。在这种情况下,您没有文件名可以帮助您,只有文件内容。)

如果你刚刚丢失了一些提交(而不仅仅是文件),你可能想要运行这样的东西:

gitk --all $( git fsck | awk '/dangling commit/ {print $3}'; git log -g --pretty='format:%H' )

这将gitk与所有分支、所有 reflog 和所有悬空提交一起运行。-n 10000如果您的 repo 有很多提交(例如 linux 内核),您可能需要添加或其他一些限制。如果您没有gitk,您可以只使用命令行运行较小的版本,如下所示:

git log --all --decorate --stat --graph --date-order $( git fsck | awk '/dangling commit/ {print $3}'; git log -g --pretty='format:%H' )

或输出不那么冗长的版本

git log --all --decorate --oneline --graph --date-order $( git fsck | awk '/dangling commit/ {print $3}'; git log -g --pretty='format:%H' )

如果您看到一些您想要保存为分支的提交recovered1,只需执行此操作git checkout -b recovered1 <sha1-of-the-commit>

于 2013-03-18T08:57:30.747 回答
7

试试这个http://gitready.com/advanced/2009/01/17/restoreing-lost-commits.html

我因失去的变化而心脏病发作。但是在关注了这篇文章之后。我拿回了我的更改

于 2013-07-22T23:06:43.020 回答
5

有一个git plugin开箱即用的方法:

https://github.com/pendashteh/git-recover-index

$ cd /path/to/disatered/repo
$ git clone git@github.com:pendashteh/git-recover-index.git $HOME/.git-recover-index
$ $HOME/.git-recover-index/git-recover-index.sh
于 2016-01-31T07:21:14.620 回答
4

实际上,如果您已将对象添加到索引中(通过使用 git add),则会为该对象的该状态创建一个 blob - 但没有引用它的树(因此,提交)对象。这就是获得“悬空”松散对象文件的方式,如果您运行 git fsck 它会显示未引用的 blob(如果运行 git gc 将删除这些类型的对象)。

因此,如果启用了 reflog,您可以使用它来尝试恢复已添加的文件 F1 的索引状态。如果您根本没有添加 F2,那么正如 Greg 所说,git 对此一无所知,并且您在那里不走运。

于 2009-07-10T11:16:24.177 回答