Turning a stash into a branch Jump to heading

Stashes are meant to be short-lived: park, switch, come back, pop. In practice the stash list fills up with entries weeks old, made on a branch that has since moved far ahead. Popping one of those onto todayโ€™s branch produces conflicts, because the stashed changes were made against code that no longer exists in that form. git stash branch sidesteps the problem. It creates a new branch at the exact commit the stash was made from, applies the stash there โ€” where it applies cleanly by definition โ€” and drops it. You then have the work as an ordinary branch you can commit, rebase and merge with the usual tools. This page shows how and when, within stashing and work-in-progress recovery.

When to use this approach Jump to heading

  • git stash pop on an old stash produces conflicts you would rather not resolve in the working tree.
  • Your stash list has entries older than a few days that represent real work.
  • You want to share stashed work with a teammate, which needs it to be a commit on a branch.
  • You are recovering a dropped stash and want to give it a proper home, after recovering a dropped stash.

Step 1 โ€” Find the stash and the commit it was made on Jump to heading

Each stash records the commit HEAD pointed to when it was created, as its first parent. The stash message includes the branch name and that commitโ€™s subject.

git stash list --date=relative
# stash@{0}: On main: quick experiment            (2 hours ago)
# stash@{3}: WIP on feature/export: 8b3e4f2 Add PDF renderer   (3 weeks ago)
git log -1 --format='%h %s' 'stash@{3}^1'      # the base commit
git rev-list --count 'stash@{3}^1..feature/export'   # how far the branch moved since
Why an old stash conflicts and stash branch does notThe stash was made on commit B. Since then the branch gained commits C1 to C3, which changed the same code. Popping the stash onto C3 must merge the stashed change with those commits. stash branch creates a branch at B and applies the stash there, where nothing has changed.apply where it was made, then integratefeature/exportBC1C2C3stash made onBstash branchBWIPthe integration with C1 to C3 then happens as a normal rebase or merge Why an old stash conflicts and stash branch does notThe stash was made on commit B. Since then the branch gained commits C1 to C3, which changed the same code. Popping the stash onto C3 must merge the stashed change with those commits. stash branch creates a branch at B and applies the stash there, where nothing has changed.apply where it was made, then integratefeature/exportBC1C2C3stash made onBstash branchBWIPthe integration with C1 to C3 then happens as a normal rebase or merge

Step 2 โ€” Create the branch from the stash Jump to heading

git stash branch <name> [<stash>] checks out a new branch at the stashโ€™s base commit, applies the stash, and drops it if the apply succeeded. The staged/unstaged split is restored as well.

git stash branch wip/pdf-page-numbers 'stash@{3}'
git status --short          # the stashed changes, applied cleanly
git log --oneline -1        # HEAD is the stash's base commit

Commit the work as a normal commit (or several) so it is safe from accidental stash operations.

git add -A
git commit -m "WIP: page numbering for PDF invoices"
git push -u origin wip/pdf-page-numbers     # optional: back it up or share it

Step 3 โ€” Bring the branch up to date Jump to heading

Now integrate the newer history with the usual tools, where conflicts are easier to handle and can be redone or reviewed.

git rebase feature/export
# resolve any conflicts commit by commit, then
git rebase --continue
Promoting an old stash to a branchPick the old stash, create a branch at its base with stash branch so it applies cleanly, commit the work, then rebase or merge the branch onto the current code where conflicts can be resolved with full history tools.Old stashstash@{3}, 3 weeksstash branchat original baseCommitsafe from dropsRebaseonto current tipContinue workor mergethe conflict still exists โ€” but now it is a normal rebase conflict, with reflog and rerere behind it Promoting an old stash to a branchPick the old stash, create a branch at its base with stash branch so it applies cleanly, commit the work, then rebase or merge the branch onto the current code where conflicts can be resolved with full history tools.Old stashstash@{3}, 3 weeksstash branchat original baseCommitsafe from dropsRebaseonto current tipContinue workor mergethe conflict still exists โ€” but now it is a normal rebase conflict, with reflog and rerere behind it

With the stash committed, a botched conflict resolution during the rebase is recoverable from the reflog, which is not true of a botched stash pop.

Step 4 โ€” Convert every old stash in one pass Jump to heading

If the stash list has accumulated, turn each meaningful entry into a branch at once. Start from the oldest so the indices of the remaining stashes do not shift under you.

git stash list --format='%gd %cr %gs'
n=$(( $(git stash list | wc -l) - 1 ))
while [ "$n" -ge 0 ]; do
  name="wip/stash-$(git log -1 --format=%cd --date=format:%Y%m%d "stash@{$n}")-$n"
  git stash branch "$name" "stash@{$n}" && git add -A && git commit -qm "WIP from stash@{$n}" && git switch -q -
  n=$((n - 1))
done

โš ๏ธ SAFETY WARNING: Each successful git stash branch drops the stash it converted, so check that the loopโ€™s branches contain what you expected before deleting anything else. If an apply fails partway, the stash is kept and the branch is left checked out with conflicts; resolve or abort before continuing the loop. A dropped stash is recoverable for a while, as described in recovering a dropped stash.

Step 5 โ€” Prefer branches for work that will outlive the day Jump to heading

The deeper fix is habit. Stashes have no names you can push, no backup on the remote, and they disappear with one wrong drop or clear. For anything you will come back to tomorrow, commit to a WIP branch or use a worktree.

When a stash should become a branchA stash made to switch branches for a few minutes is fine as a stash. Once it survives a day, it should become a branch. By a week it has likely drifted enough that only stash branch applies it cleanly, and by a month it is at real risk of being cleared.Stash is rightswitch and backminutesPromotestash branch1 dayDriftedpop would conflict1 weekAt riskclear, gc, forgotten1 montha stash is a pocket, not a filing cabinet When a stash should become a branchA stash made to switch branches for a few minutes is fine as a stash. Once it survives a day, it should become a branch. By a week it has likely drifted enough that only stash branch applies it cleanly, and by a month it is at real risk of being cleared.Stash is rightswitch and backminutesPromotestash branch1 dayDriftedpop would conflict1 weekAt riskclear, gc, forgotten1 montha stash is a pocket, not a filing cabinet

Validation checklist Jump to heading

Frequently Asked Questions Jump to heading

What if the stashโ€™s base commit no longer exists on any branch? Jump to heading

It still exists as an object โ€” the stash references it โ€” so git stash branch works regardless. The new branch simply starts from a commit no other branch contains.

Does stash branch keep the staged/unstaged split? Jump to heading

Yes. It applies with --index, so files you had staged when stashing are staged again on the new branch.

Can I push a stash directly? Jump to heading

Not as a stash, but the stash is a commit: git push origin 'stash@{0}':refs/heads/wip/thing pushes it as a branch. Converting it properly with stash branch produces a cleaner result.