Learning Objectives
By the end of this lesson you will be able to:
- Avoid the four mistakes that make stashes lose work
- Audit a stash stack you inherited or forgot about
- Recover a stash you dropped by accident
- Decide when a stash should have been a commit instead
Sharp Edge 1: The Untracked File That Stayed Behind
Covered in Lesson 4.2, and worth repeating because it is the most common:
git stash push -m "new retry helper"
git status
Untracked files:
tests/helpers/retry.js
Your tree is not clean. The new file is still there, and it will travel with you to the next branch. Half your work is stashed and half is not — which produces a beautifully confusing test failure when you switch to the hotfix.
Habit: run git status after stashing, not just before. If anything is listed, you needed -u.
Sharp Edge 2: The Stash Is Not a Backup
Stashes live in .git/refs/stash and the reflog. That means:
- They never leave your machine.
git pushdoes not include them, and no server has a copy. - If the repository folder is deleted, the stashes go with it.
- If you re-clone the repository, they do not come back.
A stash is a pocket, not a safe. Anything you would genuinely mind losing — a day's work, something a colleague may need, anything you'd have to reconstruct from memory — belongs in a commit on a pushed branch.
Sharp Edge 3: Stashes Have No Expiry
Nothing ever reminds you. A stash you made in March is still sitting there in September, holding a change you have long since rewritten differently. Then one day you find stash@{4} and spend twenty minutes working out whether it matters.
Habit: audit the stack whenever you notice it has more than two or three entries:
git stash list
For each one, look before deciding:
git stash show -p stash@{2}
Then either restore it, or drop it deliberately:
git stash drop stash@{2}
An empty stash list is a small, real pleasure.
Sharp Edge 4: Stashing Across Very Different Branches
A stash is not tied to a branch. You can pop it anywhere, and Git will try to apply the changes wherever you are standing.
Popping a stash from main onto a feature branch that has diverged for three weeks will either conflict heavily or — much worse — apply cleanly to code where it no longer makes sense. A test fixture that references a renamed function will apply without complaint and fail at runtime with a confusing error.
Habit: git stash list shows the branch each stash came from. Read it. If you're restoring onto a different branch than you stashed from, use apply rather than pop, and run the tests immediately.
Recovering a Dropped Stash
You ran git stash drop on the wrong entry, or git stash clear without looking. It is usually recoverable — for a while.
A stash is stored as a real commit object, and dropping it only removes the reference. The object survives until Git's garbage collection runs.
git fsck --unreachable | grep commit
unreachable commit a1b2c3d4e5f67890abcdef1234567890abcdef12
Inspect the candidates:
git show a1b2c3d
When you find yours, restore it:
git stash apply a1b2c3d
This works, and it is not a plan. It is a rescue for an accident, and it stops working once garbage collection runs. Treat it as the reason to look before you drop, not as permission not to.
When It Should Have Been a Commit
Use a commit instead of a stash whenever any of these is true:
- The work will still be waiting tomorrow
- Someone else might need it
- It is more than about an hour of effort
- It is worth a sentence of explanation
- You would be upset to lose it
A wip: commit on your own branch costs nothing. You can amend it, squash it, or reset it away later. It is durable, it is named, it is pushable, and it cannot silently disappear.
The stash is for the twenty-minute interruption. That is what it is good at, and it is genuinely excellent at it.
Pro Tip: Add a stash check to your end-of-day routine.
git stash listtakes one second, and finding one entry from this morning is much better than finding four from last month.
Key Takeaways
- Run
git statusafter stashing to catch untracked files the default left behind - Stashes are local-only and are not a backup — a repository deletion takes them with it
- Nothing expires or reminds you; audit the stack when it grows past two or three entries
- Restoring a stash onto a diverged branch can apply cleanly and still be wrong — test immediately
git fsck --unreachablecan rescue a dropped stash, until garbage collection runs- If the work will outlive today or matters to anyone else, commit it instead