Lesson Completion
Back to course

Recovering Stash Mistakes (Advanced)

Intermediate
8 minutes4.7Git

The Hook (The "Byte-Sized" Intro)

You ran git stash clear and wiped out 5 stashes. The reflog for stash is now empty. Game over? Not quite. Stashes are merge commits under the hood, and git fsck can find them as dangling objects. This is the advanced recovery that works when reflog fails — your last line of defense.

📖 What is Recovering Stash Mistakes (Advanced)?

When basic reflog recovery fails (e.g., after git stash clear or enough time has passed), you can use git fsck to scan the Git object database for dangling commits that represent lost stashes.

Conceptual Clarity

Stash internals — what Git actually stores: A stash entry is a special merge commit with 2-3 parents:

  • Parent 1: The commit HEAD was on when you stashed
  • Parent 2: The index (staging area) state
  • Parent 3: Untracked files (if stash -u was used)

This structure means git fsck can find them as dangling merge commits.

Recovery tools comparison:

ToolWhen to UseFinds Stashes?
git reflog show stashStash reflog exists✅ If not expired
git fsck --unreachableReflog empty or expired✅ Scans entire object DB
git fsck --danglingSame as above (alternative)✅ Only truly dangling

Real-Life Analogy

Basic recovery (reflog) is like checking your browser's "Recently Closed Tabs." Advanced recovery (fsck) is like running disk recovery software — it scans the entire drive for fragments of deleted data. Slower, but catches what the quick methods miss.

Visual Architecture

flowchart TD LOST["💀 Stashes Lost"] --> REFLOG{"git reflog show stash?"} REFLOG -->|"Has entries"| APPLY1["git stash apply SHA"] REFLOG -->|"Empty"| FSCK["git fsck --unreachable"] FSCK --> GREP["grep commit"] GREP --> SHOW["git show SHA"] SHOW --> APPLY2["git stash apply SHA"] style LOST fill:#2d1b1b,stroke:#e94560,color:#e94560 style APPLY1 fill:#1b2d1b,stroke:#53d8fb,color:#53d8fb style APPLY2 fill:#1b2d1b,stroke:#53d8fb,color:#53d8fb

Why It Matters

  • Last resort: fsck works when reflog is empty — it scans the raw object database.
  • Understanding internals: Knowing stashes are merge commits helps you identify them in fsck output.
  • Time-limited: Objects are eventually garbage collected (~30 days).
  • Professional skill: Deep recovery knowledge is rare and valuable.

Code

bash
# ─── When reflog has entries ─── git reflog show stash # If entries exist, pick the SHA and apply: git stash apply abc1234 # ─── When reflog is empty: use fsck ─── git fsck --unreachable | grep commit # Output: # unreachable commit a1b2c3d4... # unreachable commit e5f6g7h8... # unreachable commit i9j0k1l2... # ─── Inspect each dangling commit ─── git show a1b2c3d4 # Look for: # - "WIP on branch: ..." in the commit message → This is a stash! # - Your changes in the diff # ─── Apply the found stash ─── git stash apply a1b2c3d4 # Or create a branch: git branch recovered-stash a1b2c3d4 # ─── One-liner: find all stash-like commits ─── git fsck --unreachable | \ awk '/commit/ {print $3}' | \ xargs -I {} git log -1 --format="%H %s" {} | \ grep "WIP on" # Lists all dangling stash commits with their messages # ─── Prevent future loss: backup before clear ─── git stash list > stash-backup.txt git log --all --oneline $(git stash list | \ awk -F: '{print $1}') >> stash-backup.txt

Key Takeaways

  • Stashes are merge commits internally — fsck can find them as dangling objects.
  • Look for "WIP on" in dangling commit messages to identify stashes.
  • git fsck --unreachable | grep commit is your recovery command when reflog fails.
  • Act within ~30 days before garbage collection permanently removes the objects.

Interview Prep

  • Q: How are stashes stored internally in Git? A: Stashes are stored as special merge commits with 2-3 parents. Parent 1 is the HEAD commit at stash time, parent 2 is the staging area state, and parent 3 (if -u was used) contains untracked files.

  • Q: How would you recover a stash after git stash clear? A: Run git fsck --unreachable | grep commit to find dangling commits. Inspect each with git show <sha> — stash commits have "WIP on" in their message. Once found, git stash apply <sha> restores the changes.

  • Q: Why can fsck find stashes that reflog cannot? A: git stash clear removes stash reflog entries but doesn't delete the underlying commit objects from the database. fsck scans the raw object database directly, finding commits that have no references pointing to them.

Topics Covered

Git RecoveryGit Stash

Tags

#git#stash#recovery#advanced

Last Updated

2026-02-13