git reset --hard 后未暂存的文件丢失了。

16

我尝试了从git reflog中获取的git reset --hard HEAD@{n},结果丢失了所有当前未暂存的文件 :'(

这些未暂存的文件是我最后一次运行git add之前的,但在那之前,我已经尝试通过git reset返回到上一个git commit

现在我所有的文件都不见了,我无法回到上一个提交之前使用的git add命令 :'(


3
如果您使用了 git add 来将文件添加到暂存区,那么它们就不是“未暂存”的了。但是失去未暂存的更改 - 实际上是对工作树的任何更改 - 是 --hard选项的作用 - pjmorse
1
可能是 https://dev59.com/HXVD5IYBdhLWcg3wWaVh 的重复问题? - pjmorse
@pjmorse,哦,我明白了,实际上我有几个备份文件,但是太旧了。这是我的失误,不知道git reset --hard的确切含义:'( - mochadwi
1
这个回答解决了你的问题吗?如何撤销 git reset --hard HEAD~1? - Charles Duffy
9个回答

29

目前不清楚您在工作目录或索引中丢失了文件。您提到您丢失了"未暂存的文件",但之后又提到您可能运行了"git add"。对于"未暂存的文件",它们已经永久丢失了。

"已暂存的文件"可以通过以下方式恢复:

git fsck --full --unreachable --no-reflog

每添加一个文件都会产生一个丢失的blob对象,每个目录条目都会产生一个树形对象。您可以通过执行以下操作来恢复文件更改

git cat-file -p SHA

对于每个你已修改的文件

(master)$ vi bar (master)$ vi baz (master)$ vi foo (master)$ git add foo bar baz (master)$ git reset --hard HEAD HEAD is now at ead8fa2 initial (master)$ git fsck --full --unreachable --no-reflog Checking object directories: 100% (256/256), done. unreachable blob 0c29287001b29159f11c4e8a320bce7e9789c00b unreachable blob 1524d3478e3d0b92866a53239b10bcd4b3838c4d unreachable blob 97b724e770249816c61d8a526415986208ed7e15 //查看其中一个对象 (master)git cat-file -p 0c29287001b29159f11c4e8a320bce7e9789c00b changes for bar //在这里,通过检查输出,我可以确定0c29287是文件“bar” (master) git cat-file -p 0c29287 > bar

(注意:我在测试时没有遇到任何丢失的树对象,所以此部分可能无法正常工作)

如果您修改了许多文件,恢复整个树对象可能比单独恢复文件更容易

git read-tree SHA

SHA是根树的丢失树对象。


谢谢你向我展示这些命令 :) 但是,在执行 git cat-file -p SHA 命令之前,我应该先使用 cd 命令进入 源目录 吗? - mochadwi
cat-file 的输出只是文件内容。您需要检查内容并确定它对应哪个文件。然后,您将使用新内容覆盖相应的文件。该命令本身可以从任何地方运行。我会编辑答案。 - Andrew C
1
是的,我在develop分支上丢失了我的“未暂存文件”,但它也影响了我的master分支上的文件:'( #它们也消失了。 “未暂存文件”是我从develop修改的文件,在git reset --hard之后,我没有在master上做任何事情,文件也消失了T__T。 - mochadwi
非常感谢您先生 :) 最终,在执行 git reset --hard 命令之前,我找到了我的另外几个 已修改 的文件,即使只有其中的三个我能够恢复,其余的文件在执行 git fsck --full --unreachable --no-reflog 后未显示。 - mochadwi
非常感谢您,先生!您救了我于水深火热之中。 - ajayv

11

使用 --hard 选项会删除所有未提交的文件,建议不要使用。

相反,您应该先使用 stash 命令,然后再使用普通的 reset 命令。这样可以避免删除所有未提交的文件。

替代方法:

git reset --hard HEAD@{n}

你应该做

git stash
git reset HEAD@{n}

您的代码将被保存在stash堆栈中,您可以通过执行以下操作再次检索它

git stash pop

尽管此命令将“存储”更改与当前HEAD合并(存储类似于分支),但建议在生成这些存储的相同提交上执行存储恢复操作。


推荐使用stash,但我不会说--hard是“不推荐”的 - 有时您可能想要覆盖整个工作树。 - pjmorse
2
“永远不要使用--hard”,这是Scott Chacon的话。根据我的个人经验,每次有人使用“--hard”时,都会出现“哦,该死,我需要我的代码:(”。 - dseminara
也许“--hard”选项只是个人偏好的问题。以防万一,我认为这会有所帮助:http://git-scm.com/blog/2011/07/11/reset.html,“--hard”是唯一无法撤消的重置模式。在我看来,Git 的有效性在于快速处理事情,因为我们知道它可以轻松地撤消,我不习惯使用“git reset --hard”,因为我不喜欢花太多时间思考我将要删除和永远无法恢复的代码。但再次强调,这只是个人口味问题。另一个有用的链接:http://vimeo.com/32608318(抱歉,是西班牙语)。 - dseminara
@dseminara 是的,我太草率了,没有考虑清楚就使用了git reset --hard :'( 但是,我也不知道git reset --hard是否会在其他分支上删除所有文件 T__T - mochadwi
每当我尝试从备份文件夹中复制时,我无法进行“checkout”,因为它告诉我应该删除或移动这些文件,否则它们将被覆盖 >_< - mochadwi
显示剩余4条评论

10
如果有人和我一样在添加未暂存的文件之前犯了git reset --hard的错误,那么仍然有机会找回这些更改。尽管这些文件在存储库中不再可用,但一些新的IDE保留了它们自己的历史记录。就像在我的情况下,我能够从Android Studio的本地历史功能中检索我的未暂存更改,该功能位于VCS下面。 操作方法: 第1步 第2步

5

这是一个可能对一些人有用的低技术提示。如果您丢失的未暂存/未提交文件在您的编辑器中打开,请尝试在该文件上执行撤销操作,您应该会从编辑器的历史堆栈中获得“以前的版本”。


1
我会称之为一个聪明的提示。 - Hassan Baig

3

与UsamaAmjad和Juank的回答类似。

如果你使用的是足够好的IDE/编辑器:

  • 在每个已修改的文件上按Ctrl+Z,
  • 如果你很幸运(像我一样),你将看到一个弹出窗口,“撤消从磁盘重新加载”
  • 点击“是”。

注意:

  • 这对我的未暂存文件有效
  • 我是在PyCharm中进行的操作,所以它可能适用于其他JetBrains/Idea-based IDEs
  • 在git reset时,IDE可能需要处于打开状态
  • 在git reset时,文件可能需要在编辑器窗口中打开。

1
补充一下,我在 VS Code 中打开了一个文件,它的更改被 git reset --hard 抹掉了,在我的情况下,使用撤销操作也能找回未暂存的更改。 - Deniz Genç

3

如果有人在使用Pycharm IDE的过程中遇到问题,可以按照以下步骤找回删除文件:

  • 找到被删除文件所在的文件夹。
  • 右键点击该文件夹,选择“显示历史记录”。
  • 在左侧面板中,您将看到该文件夹中更改的历史记录。

然后找到您删除的文件,在其上单击右键,并选择“还原”,此时已删除的文件将出现在文件夹中。


挽救了我的生命。还恢复了未暂存的文件。 - onetuser

1
如果你使用git add将文件暂存,那么它仍然可以找回。但是如果文件没有被暂存,我不得不说没有办法。:(
请记住,git reset真的不安全,特别是对于未暂存的文件。
但是如果这些文件真的非常重要,我能想到的是停止在硬盘上修改任何数据,并使用finaldata等工具进行磁盘恢复。如果运气好的话,它可能会找回一些东西,因为你已经在git reset后覆盖了一些文件。
无论如何,如果你熟悉它,Git确实是一个强大而酷的工具。

是的,我确实缺乏git知识:'( 在使用像finaldata服务之前,我还有一些选项,虽然我有旧的备份文件,但它们太旧了>_<,现在我明白了在使用git reset之前需要考虑的高风险:)非常感谢您! - mochadwi
NP。备份文件始终是有用且强大的,尽管不太花哨。有时候,如果我不确定该做什么,我只是会进行备份。 :) - Landys
是的,我同意你的观点!我也是 :D 备份,备份,永远记得备份,除非我们遇到存储不足的情况 T__T - mochadwi

0

又是一个关于“如果你正在使用特定的IDE”的答案...

如果你正在使用IntelliJ(或我怀疑任何其他JetBrains IDE),那么你可以:

  • 右键单击文件所在的文件夹
  • 选择“本地历史记录 -> 显示历史记录”
  • 向下浏览“外部更改”项目,直到找到显示所有已删除文件的项目。
    • 它看起来像“reset --hard”在IntelliJ中显示为多个文件删除,因此列表中可能有多个“外部更改”。请向下滚动到最后一个时间戳大约在您进行重置时
  • 右键单击“外部更改”,然后单击“还原”

更多细节: https://blog.jetbrains.com/idea/2020/02/local-history-in-intellij-idea-may-save-your-life-code/


0

这个想法与以上所有内容非常相似,但在我的情况下,我之前写过git status,并在终端中列出了所有更改的文件列表,我可以从中复制文件列表,然后逐个在Visual Code上打开文件(希望它仍然有文件更改的缓存)。检查一下是否在某个地方有文件列表,并希望您的编辑器已经保存了缓存副本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接