协慌网

登录 贡献 社区

如何恢复 Git 中丢失的存储?

我经常使用git stashgit stash pop来保存和恢复工作树中的更改。昨天我的工作树上有一些变化,我已经藏起来了,然后我对工作树做了更多改动。我想回去查看昨天发生的变化,但是git stash pop似乎删除了对相关提交的所有引用。

我知道如果我使用git stash那么.git / refs / stash 包含用于创建存储的提交的引用。而.git / logs / refs / stash 包含整个存储。但是这些引用在git stash pop之后就消失了。我知道提交仍然在我的存储库中,但我不知道它是什么。

有没有一种简单的方法来恢复昨天的隐藏提交引用?

请注意,这对我来说并不重要,因为我有每日备份,可以回到昨天的工作树来获取我的更改。我问,因为必须有一个更简单的方法!

答案

一旦你知道你删除的存储提交的哈希值,你可以将它作为存储应用:

git stash apply $stash_hash

或者,您可以为其创建单独的分支

git branch recovered $stash_hash

之后,您可以使用所有常规工具执行任何操作。当你完成后,只需将树枝吹走。

找到哈希

如果你刚刚弹出它并且终端仍然打开,你仍然会在屏幕上显示由git stash pop打印的哈希值 (感谢,Dolda)。

否则,你可以在 Linux,Unix 或 Git Bash for Windows 中找到它:

git fsck --no-reflog | awk '/dangling commit/ {print $3}'

... 或者使用 Powershell for Windows:

git fsck --no-reflog | select-string 'dangling commit' | foreach { $bits = $_ -split ' '; echo $bits[2];}

这将向您显示提交图提示中的所有提交,这些提交不再从任何分支或标记引用 - 每个丢失的提交(包括您创建的每个存储提交)都将位于该图中的某个位置。

找到所需存储提交的最简单方法可能是将该列表传递给gitk

gitk --all $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' )

... 或者如果使用 Powershell for Windows,请查看emragins 的答案

这将启动一个存储库浏览器,显示存储库中的每个提交 ,无论它是否可访问。

你可以用git log --graph --oneline --decorate替换gitk ,如果你喜欢在一个单独的 GUI 应用程序上的控制台上有一个漂亮的图形。

要查找存储提交,请查找此表单的提交消息:

somebranch 上的 WIP: commithash 一些旧的提交消息

注意 :如果您在执行git stash时没有提供消息,则提交消息将仅采用此形式(以 “WIP on” 开头)。

如果你没有关闭终端,只需查看git stash pop的输出,你将拥有被删除的存储的对象 ID。它通常看起来像这样:

$ git stash pop
[...]
Dropped refs/stash@{0} (2ca03e22256be97f9e40f08e6d6773c7d41dbfd1)

(注意git stash drop也会生成相同的行。)

为了获得那个存储,只需运行git branch tmp 2cae03e ,你就可以将它作为一个分支。要将其转换为存储,请运行:

git stash apply tmp
git stash

将它作为分支也允许您自由地操纵它; 例如,樱桃挑选或合并它。

只是想提到对已接受的解决方案的这一补充。我第一次尝试这种方法时并不是很明显(也许应该是这样),但是要从哈希值中应用存储,只需使用 “git stash apply”:

$ git stash apply ad38abbf76e26c803b27a6079348192d32f52219

当我刚接触 git 时,这对我来说并不清楚,我正在尝试 “git show”,“git apply”,“patch” 等的不同组合。