如何恢复Git中丢弃的暂存

如何恢复Git中丢弃的暂存

技术背景

在使用Git进行版本控制时,git stash 是一个非常实用的命令,它可以将当前工作目录和暂存区的修改保存起来,让你可以切换到其他分支进行工作。然而,有时候我们可能会不小心丢弃了某个暂存(stash),这时就需要恢复这个丢失的暂存。

实现步骤

1. 找到丢弃暂存的哈希值

  • 如果终端未关闭:如果刚刚执行了 git stash popgit stash drop 且终端还未关闭,可以直接从命令输出中找到丢弃暂存的哈希值。例如:
1
2
3
$ git stash pop
[...]
Dropped refs/stash@{0} (2ca03e22256be97f9e40f08e6d6773c7d41dbfd1)

这里的 2ca03e22256be97f9e40f08e6d6773c7d41dbfd1 就是丢弃暂存的哈希值。

  • 通过 git fsck 查找
    • Linux、Unix 或 Git Bash for Windows
1
git fsck --no-reflog | awk '/dangling commit/ {print $NF}'
- **PowerShell for Windows**:
1
git fsck --no-reflog | select-string 'dangling commit' | foreach { $_.ToString().Split(" ")[-1] }

这个命令会列出所有不再被任何分支或标签引用的提交,包括所有丢失的暂存提交。

2. 使用找到的哈希值恢复暂存

  • 应用暂存
1
git stash apply $stash_hash
  • 创建新分支
1
git branch recovered $stash_hash

核心代码

查找丢失暂存的哈希值

  • Linux、Unix 或 Git Bash for Windows
1
git fsck --no-reflog | awk '/dangling commit/ {print $NF}'
  • PowerShell for Windows
1
git fsck --no-reflog | select-string 'dangling commit' | foreach { $_.ToString().Split(" ")[-1] }

恢复暂存

  • 应用暂存
1
git stash apply $stash_hash
  • 创建新分支
1
git branch recovered $stash_hash

最佳实践

  • 使用 gitk 可视化查找
1
gitk --all $( git fsck --no-reflog | awk '/dangling commit/ {print $NF}' )

或者在 PowerShell for Windows 中:

1
gitk --all $( git fsck --no-reflog | select-string 'dangling commit' | foreach { $_.ToString().Split(" ")[-1] } )

这会打开一个仓库浏览器,显示仓库中的所有提交,方便你找到需要的暂存提交。

  • 使用自定义命令查找
1
git log --oneline  $( git fsck --no-reflogs | awk '/dangling commit/ {print $3}' )

这个命令可以快速列出所有可能的丢失提交。

常见问题

1. 在 Windows 简单命令窗口中无法使用 awkgrepSelect-string

可以使用以下方法:

  • 运行 git fsck --unreachable | findstr "commit"
  • 将输出复制到记事本中,将 unreachable commit 替换为 start cmd /k git show
  • 保存为 .bat 文件并运行。
  • 找到需要的提交后,运行 git stash apply (your hash)

2. 无法找到丢失的暂存

  • 检查是否使用了正确的命令,确保没有遗漏参数。
  • 如果暂存保存时添加了自定义消息,可以在查找命令中使用 -grep 选项过滤,例如 -grep=Tesselation
  • 如果还是无法找到,可以尝试使用 git reflog 查看所有引用的变更记录,从中找到丢失的暂存。

如何恢复Git中丢弃的暂存
https://119291.xyz/posts/2025-05-13.how-to-recover-a-dropped-stash-in-git/
作者
ww
发布于
2025年5月13日
许可协议