Git Stash 丢失后的完整找回指南

场景:本地分支有未提交的 git stash,合并远程分支后 stash 从列表消失,代码"不见了"。


事故还原

  1. 在本地分支 test-eslint-copy 上做了大量修改(props 清理、字段删除等)
  2. 用 git stash 暂存了这些改动
  3. 执行 git merge origin/test 合并远程分支
  4. 合并后发现 git stash list 里没有了自己的 stash,改动"消失"

根本原因 :git stash 的记录存储在 refs/stash 引用链上。某些 git 操作(如带冲突的 merge、reset 等)会导致 stash 引用丢失,但 stash 的 commit 对象本身还在 git 对象库里,只是变成了"悬空对象(dangling commit)",没有任何引用指向它。


找回步骤

第一步:确认 stash list 里真的没了

bash 复制代码
git stash list

如果你的 stash 不在里面,继续下一步。

第二步:用 fsck 找出所有悬空的 commit

bash 复制代码
git fsck --unreachable 2>&1 | grep "unreachable commit"

这会列出所有"孤儿 commit",stash 就藏在里面。

第三步:过滤出属于你分支的 stash

stash commit 的 message 格式固定为 WIP on <分支名>: <hash> <commit message>,用这个特征过滤:

bash 复制代码
git fsck --unreachable 2>&1 | grep "unreachable commit" | awk '{print $3}' | while read c; do
  msg=$(git log -1 --format="%s %ci" $c 2>/dev/null)
  if echo "$msg" | grep -q "WIP on <你的分支名>"; then
    echo "$c | $msg"
  fi
done

把 <你的分支名> 替换成实际分支名,比如 test-eslint-copy。

输出示例:

sql 复制代码
469b4f36... | WIP on test-eslint-copy: 23996d8 fix: 再次处理eslint问题 2026-04-28 10:03:30 +0800
bcb74bf5... | WIP on test-eslint-copy: 14aa429 Merge branch 'test' 2026-04-28 09:54:12 +0800

第四步:确认是不是你要的那个

根据时间戳判断,然后看改动内容:

bash 复制代码
git show <commit-hash> --stat

第五步:恢复

先处理工作区的干扰文件(如果有),再 apply:

bash 复制代码
# 如果有自动生成的文件挡路,先丢弃
git checkout -- src/dts/auto-imports.d.ts src/dts/components.d.ts

# 恢复 stash
git stash apply <commit-hash>

关键原理

概念 说明
git stash 本质是创建了 2~3 个特殊 commit,用 refs/stash 引用链串起来
stash 丢失 只是引用链断了,commit 对象本身还在对象库
dangling commit 没有任何引用指向的 commit,git fsck 可以找到
git gc 垃圾回收,会清理 dangling 对象。找回操作要在 gc 之前做!

预防措施

合并前养成习惯:

bash 复制代码
# 合并前先把 stash 转成真正的 commit
git stash pop
git add .
git commit -m "wip: 临时保存"

# 合并完再 reset 回来
git merge origin/xxx
git reset HEAD~1  # 把临时 commit 变回工作区改动

或者更简单,用 --autostash:

bash 复制代码
git merge --autostash origin/xxx

这样 git 会在合并前自动 stash、合并后自动 pop,不会丢。


总结一句话

stash 丢了不要慌,git fsck --unreachable 找悬空 commit,按时间戳认出来,git stash apply <hash> 直接恢复。只要没跑 git gc,数据就还在。

相关推荐
2601_958352908 分钟前
23.5×19mm 换掉一整条音频链?|A-68 集成了什么:ADC / DAC / 24.576MHz 时钟 / AEC / 波束降噪,主控仅需 6 根线
前端·音视频·ai降噪·回声消除·语音模块
志尊宝1 小时前
AI原生前端开发(039):AI辅助的Nuxt 4全栈开发
前端·vue.js·ai-native
FRing032 小时前
JavaScript入门到精通三十二(深拷贝、浅拷贝、递归函数)
开发语言·前端·javascript
excel2 小时前
双 Token 与前端使用 Crypto 公私钥鉴权换 Token,哪种方案更好?
前端·后端
外收内放2 小时前
Python基础语法练习题(73)
java·前端·python
风骏时光牛马3 小时前
面向复杂场景的大模型应用落地与能力优化实践
前端
小小善后师3 小时前
我做了个病历归档小程序,被 AI 识别的"最后一公里"狠狠上了一课
前端
H_Lisa3 小时前
我用 Express 写了个 MCP,Claude 直接调用我的 API 了
前端
IT_陈寒3 小时前
React的useEffect依赖数组把我坑惨了
前端·人工智能·后端
兰亭妙微UI设计公司4 小时前
兰亭妙微ui设计公司分享:B端组件命名如何支持团队协作
前端·javascript·vue.js