Creating a Branch from a Stash
Sometimes a stash refuses to apply cleanly because the world has moved on since you saved it — main got dozens of new commits, a file was renamed, an API was reshaped. git stash branch is the elegant fix: it recreates the exact commit you were on when you stashed, applies the stash there, and drops it on success. You get a fresh branch with your work intact, and you can merge or rebase it forward on your own terms.
The command
One-liner that does a lot
git stash branch <new-branch-name> [<stash>]
# Default stash is stash@{0}
git stash branch rescue/login-validation
# Or pick a specific stash
git stash branch rescue/old-cart stash@{3}What it actually does, step by step
- Finds the commit you were on when you stashed (stored in the stash itself).
- Creates a new branch starting at that commit.
- Checks out the new branch — your working tree now matches that older state.
- Applies the stash onto it — which, by definition, applies cleanly because it's the same base.
- Drops the stash from the stack (only if the apply succeeded).
The picture
Before:
main: A───B───C───D───E (HEAD)
▲
│
stash made here, on commit B
After git stash branch rescue/old :
main: A───B───C───D───E
\
rescue/old: B' (HEAD)
▲
│
stash applied cleanly
on the original baseWhen this beats a normal pop
Plain git stash pop tries to apply onto your current HEAD, whatever that is. If your branch has moved a lot, you may face a wall of conflicts — through no fault of the stash. stash branch sidesteps the problem entirely.
Scenario | Best command | Why |
|---|---|---|
Stashed minutes ago, branch hasn't moved |
| Fastest, no extra branch. |
Stashed a week ago, branch moved a lot |
| Restores the original base; no conflicts from drift. |
Pop conflicted and you want to retry on the old base |
| You don't have to wrestle the merge. |
You want to promote a stash to permanent work |
| Gives you a branch you can push and PR. |
Quick branch switch and return |
| Stash branch is overkill. |
A worked example
Rescue an old stash
git stash list
# stash@{0}: On main: WIP rate-limiting middleware (10 days ago)
# Trying to pop fails messily
git stash pop
# CONFLICT (modify/delete): src/middleware/auth.js deleted in HEAD ...
# Auto-merging src/router.js
# CONFLICT (content): Merge conflict in src/router.js
# (4 conflicts, you sigh)
# Abort, try the better tool
git checkout -- .
git reset HEAD
git stash branch rescue/rate-limiting
# Switched to a new branch 'rescue/rate-limiting'
# On branch rescue/rate-limiting
# Changes not staged for commit:
# modified: src/router.js
# new file: src/middleware/rate-limit.js
# Dropped refs/stash@{0} (a1b2c3d...)
# Now commit and rebase onto current main
git add -A
git commit -m "WIP: rate-limiting middleware"
git rebase main
# Resolve conflicts one commit at a time — much easierCompared with doing it by hand
The manual equivalent (for understanding)
# stash@{0} stores the parent commit it was created from
ORIG=$(git rev-parse "stash@{0}^")
git switch -c rescue/old "$ORIG"
git stash apply
git stash dropThat's essentially what git stash branch runs. Knowing the manual form is useful when you want to apply the same stash to multiple branches based at the original commit, or to scriptify recovery.
Real-world recipe: promote forgotten WIP
From buried stash to PR-able branch
# Wednesday-morning audit
git stash list
# That "WIP search" from two sprints ago looks worth saving
git stash branch feature/search-from-stash stash@{4}
# You're on a fresh branch with the work applied. Commit it.
git add -A
git commit -m "WIP: search bar with debounced input"
# Bring it up to date with main
git fetch origin
git rebase origin/main
# Resolve conflicts (now they're manageable, not catastrophic)
git push -u origin feature/search-from-stash
# Open PR. Done.What if the apply still fails?
It's rare — the whole point is that the base matches — but it can happen if your tree had untracked files that now collide. In that case Git refuses to drop the stash, and you're left on the new branch with a conflict to resolve. Resolve it, then drop the stash manually.