在执行git重置后恢复添加/暂存的文件--硬头^?

在执行git重置后恢复添加/暂存的文件--硬头^?,git,version-control,recovery,Git,Version Control,Recovery,我添加了一个新文件F1,并对另一个文件F2进行了更改,但随后执行了“git reset--hard HEAD^”,并且丢失了对文件的所有更改 有什么办法,我能把他们弄回来吗 我确实在这里看了一个相关的问题:但是,这个问题假设一个已经完成了git提交。实际上,如果您已经将对象添加到索引中(通过使用git add),那么会为该对象的状态创建一个blob,但是没有引用它的树(因此,提交)对象。这就是获得“悬空”松散对象文件的方式,如果运行git fsck,它将显示未引用的blob(如果运行git gc

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

有什么办法,我能把他们弄回来吗


我确实在这里看了一个相关的问题:但是,这个问题假设一个已经完成了git提交。

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

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

您可以(通过一些工作)在最后一次“git添加”时恢复文件的状态。你可以用

$ git fsck --cache --no-reflogs --lost-found --dangling HEAD
然后检查“.git/lost-found/other”目录中的文件

请阅读手册。

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

  • 获取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
    
  • 如果您看到一些有趣的内容,
    git cat file blob SHA-1-of-interest-file
    将文件输出为标准输出。(示例:
    git cat文件blob b8f0bdf56>恢复的logo.png

  • 不幸的是,若丢失的文件不是任何提交的一部分,git并没有时间戳,所以您不能打印按时间排序的文件的各种版本

    如果丢失的文件从未被暂存(
    git-stage
    git-add
    )或隐藏(
    git-stash
    ),那么您就很倒霉了,因为据git所知,该文件从未存在过。(您仍然可以尝试执行
    git fsck--no reflogs--lost-find
    并在目录
    .git/lost-find/other
    中四处查看,看看是否有任何值得保留的内容,以防git因某种幸运的意外而确实拥有丢失文件的副本。在这种情况下,您没有文件名来帮助您,只有文件内容。)

    如果您刚刚丢失了一些提交(而不仅仅是文件),您可能会希望运行以下内容:

    gitk --all $( git fsck | awk '/dangling commit/ {print $3}'; git log -g --pretty='format:%H' )
    
    git log --all --decorate --stat --graph --date-order $( git fsck | awk '/dangling commit/ {print $3}'; git log -g --pretty='format:%H' )
    
    它将使用所有分支、所有reflog和所有悬空提交运行
    gitk
    。您可能需要添加
    -n1000
    或其他一些限制,以防您的repo有很多提交(比如linux内核)。如果您没有
    gitk
    ,您可以只使用以下命令行运行较低版本:

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


    我因为失去了改变而心脏病发作。但是看完这篇文章之后。我找回了我的更改

    有一个git插件,它可以做到这一点:


    git show-p--format=raw$blob>$blob.txt
    +1,救了我的命。似乎在git 1.9.1上,--无法访问的原因。git/lost-found未被创建声明-无法访问阻止创建“.git/lost-found”。我用下面的$git-fsck实现了它——缓存——无回流——失物招领——悬垂的头目哦,天哪,这救了我的命!谢谢雅各布和雅各布。你在不同的国家是同一个人吗?这似乎有效,但我丢失了所有的文件扩展名?呸!谢谢:)你会来的:)很高兴它帮了我的忙。6年后,这个答案救了我,谢谢!现在有一个git脚本可以直接实现这一点:哇!刚刚找到了一个未跟踪的文件,它被我意外地丢弃(甚至没有提交),使用
    git fsck--no reflogs--lost-found
    ,然后在目录
    .git/lost-found/other
    (使用Notepade++的Find-in-Files-search)中搜索它。非常感谢。我必须补充一点,我郑重建议进行自动版本备份,而不是尝试从git history恢复文件。omg谢谢@奥菲尔,我也一样!!$git fsck--无重登录--失物招领“然后搜索“.git/lost-found/other”中的文件