Git Stash Drop by Mistake, How to Recover Lost Changes
Accidentally dropping a stash isn't necessarily permanent data loss — a stash is internally implemented as a set of commits, and dropping it only removes the reference pointing to those commits, not the commits themselves, which Git usually keeps around for a while before actual garbage collection.
The Problem
You run git stash drop (or git stash pop, which drops automatically on success) and realize immediately afterward that you needed those changes, or dropped the wrong stash entirely from a list of several:
git stash drop stash@{1}
Dropped stash@{1} (a1b2c3d4e5f6...)
The stash no longer appears in git stash list, and the changes seem to be gone.
Why It Happens
A Git stash is implemented internally as a special kind of commit (actually usually two commits — one for the working directory state, one for the index) that a stash reference points to. Dropping the stash removes that reference, but the underlying commit objects themselves aren't immediately deleted — Git's garbage collection only removes genuinely unreferenced objects after they've been unreferenced for a while (30 days by default for most object types), meaning a recently dropped stash is very likely still recoverable.
The Fix
First, check Git's fsck (file system check) for dangling commits, which specifically surfaces commit objects that exist but aren't reachable from any branch or reference — exactly the state a recently dropped stash is left in:
git fsck --unreachable | grep commit
This lists commit hashes that aren't currently referenced by anything. Since you likely dropped the stash recently, look for one with a timestamp matching approximately when you created or dropped the stash.
Once you've identified a likely candidate hash, inspect it to confirm it's genuinely the stash you're looking for before doing anything else:
git show <commit-hash>
If this shows the changes you expected to find in the dropped stash, recover it by creating a new branch pointing at that commit, or by directly applying it as a stash-like patch:
git branch recovered-stash <commit-hash>
git checkout recovered-stash
Alternatively, to bring the recovered changes directly into your current working directory rather than a separate branch, apply the commit as a stash-style diff:
git stash apply <commit-hash>
This works because a stash commit, despite no longer being tracked in the stash list, is still a genuine commit object that git stash apply can operate on directly by hash, exactly as if it were still listed normally.
If git fsck --unreachable returns many results and it's hard to identify the right one among several unreferenced commits, narrow the search by also checking the reflog, which sometimes retains a more directly identifiable reference to the stash operation itself:
git fsck --unreachable | grep commit | cut -d' ' -f3 | xargs -I{} git log -1 --format="%H %ci %s" {}
This prints the commit message and timestamp for each dangling commit found, making it much easier to visually identify the correct one by its stash message (which typically includes the branch name and a summary of the top commit at the time it was stashed) rather than working from bare hashes alone.
Still Not Working?
If git fsck --unreachable returns nothing relevant, the commit may have already been garbage collected, which happens if significant time passed since the drop, or if garbage collection ran manually or automatically in the meantime (git gc, which some Git operations trigger automatically under certain conditions). In that case, the changes are very likely genuinely unrecoverable through Git itself — check whether your editor maintains its own local history or backup files (many modern editors keep a local edit history independent of Git specifically for this kind of scenario), since that's typically the only remaining recovery path once Git's own object store no longer has the data.