GitStash丢失后的完整找回指南

Written by

in

文章目录
  • 在本地分支 test-eslint-copy 上做了大量修改(props 清理、字段删除等) 用 git stash 暂存了这些改动 执行 git merge origin/test 合并远程分支 合并后发现 git stash list 里没有了自己的 stash,改动"消失" 根本原因:git stash 的记录存储在 refs/stash 引用链上。某些 git 操作(如带冲突的 merge、reset 等)会导致 stash 引用丢失,但 stash 的 commit 对象本身还在 git 对象库里,只是变成了"悬空对象(dangling commit)",没有任何引用指向它。
  • 概念 说明 git stash 本质是创建了 2~3 个特殊 commit,用 refs/stash 引用链串起来 stash 丢失 只是引用链断了,commit 对象本身还在对象库 dangling commit 没有任何引用指向的 commit,git fsck 可以找到 git gc 垃圾回收,会清理 dangling 对象。找回操作要在 gc 之前做!
  • 合并前养成习惯: # 合并前先把 stash 转成真正的 commit git stash pop git add . git commit -m “wip: 临时保存” # 合并完再 reset 回来 git merge origin/xxx git reset HEAD~1 # 把临时 commit 变回工作区改动 或者更简单,用 –autostash: git merge –autostash origin/xxx 这样 git 会在合并前自动 stash、合并后自动 pop,不会丢。
  • stash 丢了不要慌,git fsck –unreachable 找悬空 commit,按时间戳认出来,git stash apply <hash> 直接恢复。只要没跑 git gc,数据就还在。 到此这篇关于Git Stash丢失后的完整找回指南的文章就介绍到这了,更多相关Git Stash丢失找回指南内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: 一文详解Git的暂存与stash功能 idea中操作git shelve与git stash全过程 git stash命令基本用法详解 git版本回退方式(git reset、git revert、git stash) git stash使用场景及常见方法详解
  • 目录
    • 事故还原
    • 找回步骤
      • 第一步:确认 stash list 里真的没了
      • 第二步:用 fsck 找出所有悬空的 commit
      • 第三步:过滤出属于你分支的 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)",没有任何引用指向它。

          git stash list

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

          git fsck --unreachable 2>&1 | grep "unreachable commit"
          

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

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

          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

          输出示例:

          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
          

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

          git show <commit-hash> --stat
          

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

          # 如果有自动生成的文件挡路,先丢弃
          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 之前做!

          合并前养成习惯:

          # 合并前先把 stash 转成真正的 commit
          git stash pop
          git add .
          git commit -m "wip: 临时保存"
          
          # 合并完再 reset 回来
          git merge origin/xxx
          git reset HEAD~1  # 把临时 commit 变回工作区改动
          

          或者更简单,用 --autostash

          git merge --autostash origin/xxx
          

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

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

          到此这篇关于Git Stash丢失后的完整找回指南的文章就介绍到这了,更多相关Git Stash丢失找回指南内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!

          您可能感兴趣的文章:

          • 一文详解Git的暂存与stash功能
          • idea中操作git shelve与git stash全过程
          • git stash命令基本用法详解
          • git版本回退方式(git reset、git revert、git stash)
          • git stash使用场景及常见方法详解

          站内搜索