如何撤销git stash clear操作

96

我执行了git stash save "ABC"命令。
然后错误地执行了git stash clear命令。 我该如何恢复之前保存在ABC中的数据?


1
没有任何答案适用于我,但是这里解释的那个确实管用。我认为它也可能会帮助其他人。 - Val
6个回答

153

正如在git stash文档中所述,如果以下操作生效,您可能很幸运:

恢复被错误清除/丢弃的隐藏内容

如果您错误地删除或清除了隐藏内容,它们将无法通过常规安全机制进行恢复。但是,您可以尝试以下方法来获取仍存在于存储库中但不可访问的隐藏内容列表:

git fsck --unreachable | grep commit | cut -d\ -f3 | xargs git log --merges --no-walk --grep=WIP

如果找到了误清除的隐藏内容,则可以执行以下操作:

git stash apply <stash>

编辑:请使用以下命令:git fsck --unreachable | grep commit | cut -d ' ' -f3 | xargs git log --merges --no-walk --grep=WIP


6
@AshishBanker: 然后它就消失了。让这成为一个教训,不要使用 git stash 存储你关心的更改,而是使用 git commit,即使只有部分更改也可以。之后你总是可以使用 git commit --amendgit rebase -i - Madara's Ghost
23
在Mac OSX上:git fsck --unreachable | grep commit | cut -d ' ' -f3 | xargs git log --merges --no-walk --grep=WIP - David Andreoletti
3
cut的参数不正确。在反斜杠之后应该有两个空格,因为Markdown解释器会去掉其中一个空格。如@JJS所建议的,将-d ' '或-d " "作为cut的第一个参数。 - chmike
1
我在 IntelliJ IDEA 中犯了这个错误。幸运的是,它有自己的版本控制系统。所以你可以使用 VCS > Local History > Show History 每个你修改过的文件(是的,你必须记住每个你修改过的文件)。 - Simon Logic
5
在Windows上使用git bash时,它对我非常有效。 它是一个相当强大的工具,可以恢复“存储”。 git stash apply <commit SHA>。 由于我意外清除了我的存储列表,所以没有感到需要使用git stash pop - Jitendra
1
所有这些命令都附加了--grep=WIP这只有在没有为存储区命名的情况下才会发生,因为默认情况下,存储区的名称是"WIP on ..."! @AshishBanker实际上为存储区命名了,所以grep会跳过它。对我来说也是一样,去掉--grep=WIP后,我在列表的顶部找到了我删除的存储区。 - undefined

55

以上所有答案都以 git stash apply [commit] 结尾,虽然可以实现部分撤销,但不是完全撤销 git stash clear 的操作。为了完全撤销,您需要重新存储孤立的存储提交。我在 这些说明 中找到了方法,但是还需要一个标志才能成功。总结如下:

  1. 查找孤立的存储提交:git fsck --unreachable | grep commit | cut -d ' ' -f3 | xargs git log --merges --no-walk
  2. 重新存储提交:git update-ref --create-reflog refs/stash 4b3fc45c94caadcc87d783064624585c194f4be8 -m "My recover stash"

太棒了@studog!对我有用。我会添加3. git stash apply。 - Jose Rondon
@JoseRondon git stash apply会将存储的内容应用到你的工作树中,这超出了恢复意外删除的存储内容的范围。然而,确实有一种好的方法来防止重复错误,那就是应用存储内容,然后提交它,而不是存储它。 - studog

8

运行以下命令以查找提交记录:

git fsck --unreachable | grep commit | cut -d ' ' -f3 | xargs git log --merges --no-walk --grep=WIP

将列出类似以下的内容:

Checking object directories: 100% (256/256), done.
commit c36e565014d9a927c36f16e78bc327eb375d33b8
Merge: dff6bc1 4e05a0c
Author: suhailvs <suhailvs@gmail.com>
Date:   Thu Jul 19 13:32:01 2018 +0530

WIP on master: dff6bc1 added menu

然后检出该提交c36e565014

git checkout c36e565014

8

我必须使用

git fsck --unreachable | grep commit | cut -d ' ' -f3 | xargs git log --merges --no-walk

获取所有孤立的储藏库,将会给出类似这样的输出结果:

Checking object directories: 100% (256/256), done.
Checking objects: 100% (395/395), done.
commit 3928306034b292770cc4cd2987c034ffad250e0b    //commit stash hash
Merge: 16056a0 ac3c354
Author: Jimmy <mail>
Date:   Thu Nov 14 17:31:05 2019 +0530

    On profile: stashing for

commit 50f6f3a7161dd44bfcef2b8328a2329db4c7ec34

并使用

git apply stash 3928306034b292770cc4cd2987c034ffad250e0b

我成功找回了被隐藏的修改内容。感谢 https://mobilejazz.com/blog/how-to-recover-a-deleted-git-stash/


3
我认为你最后一条指令正确的书写方式是:'git stash apply 3928306034b292770cc4cd2987c034ffad250e0b'。 - Djamel F.
@DjamelF。这是正确的修正方式 ;) - Leonid Usov

0

我也删除了一个stash,但是使用GitKraken图形界面,所以我不知道它执行了哪些git命令。选定的答案对我没有用,但至少让我找到了正确的方向。

在我的情况下,手动搜索--unreachable对象起作用了。我相信有更有效的方法,但我很高兴能够恢复这些更改。

ids=`git fsck --unreachable | grep blob | cut -d ' ' -f3`
number_of_ids=`echo $ids | wc -l | tr -d '[:space:]'`
for i in {1..$number_of_ids}; do git show `echo $ids | sed -n ${i}p` > evaluate$i.rb;done; 

所以这将所有不可达的对象保存到以“评估”为前缀的文件中。然后我在文本编辑器(对我来说是sublime subl evaluate*)中打开了所有文件,并逐个评估了每个文件,如果它是从我删除的存储库中的文件,则手动将该文件复制并粘贴到原始文件的旧版本中。

提示:

  • 更改.rb以匹配您要查找的文件的文件扩展名,以获取适当的语法突出显示(如果需要)。
  • 如果您的文件未包括在内,则可以通过去掉| grep blob 来扩大搜索范围(我的文件位于blob中)。

-2
在项目结构中,左侧右键单击您的项目。然后选择“本地历史记录”->“显示历史记录”,请查看屏幕截图。它会显示本地更改列表,您可以在左侧查看相应的更改。
要应用更改,请右键单击所选项,它会给出两个选项: 1)还原 2)创建补丁

enter image description here


这与Git无关,它是Jetbrains IDE的一个功能。 - Ariel Mirra
Git的方式是获取所有孤立的存储,然后git stash应用您想要的那一个。 - Ariel Mirra
我实际上点赞了这个回答,因为它帮助我恢复了大部分的文件。即使问题中指定了 Git,我认为这个回答也不应该被忽视。 - Jordan Mackie

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