Moving uncommitted work to the right branch Jump to heading

Everyone does it: an hour into a change, git status reveals you are on the default branch, or on the branch from last week’s ticket. The work is fine; its location is not. Git handles this better than its reputation suggests β€” uncommitted changes usually travel with a branch switch, and where they cannot, the stash or a scratch commit covers it. The one thing to avoid is the panicked git checkout that discards them. This recipe covers each case, within stashing and work-in-progress recovery.

When to use this approach Jump to heading

  • Work in progress is on the wrong branch and you noticed before committing.
  • You committed to the wrong branch and want to move the commits.
  • Some of the changes belong on one branch and some on another.
  • A branch switch was refused because it would overwrite local changes.
  • If you have already committed and pushed, this is a different problem β€” cherry-pick and revert instead.

Step 1 β€” Try the simple switch first Jump to heading

Git carries uncommitted changes across a switch whenever doing so is unambiguous.

git status --short
git switch -c feat/PAY-812-refund-window
# The changes come with you; nothing was stashed or committed
git status --short
git rev-parse --abbrev-ref HEAD
# Verification: the original branch is unchanged
git diff --stat main

This works whenever the files you have modified are identical in both branches, which is the overwhelmingly common case when the new branch is created from the current commit. A switch to an existing branch with different content in those files is the case Step 2 covers.

Which move appliesCreating a new branch from where you are always carries the changes. Switching to an existing branch works when the modified files are the same in both. Only when they differ does the switch fail, and that is what the stash is for.Where does the work need to go?a new branch from heregit switch -cchanges come with youan existing branchTry itstash if refusedalready committed hereMove the commitsreset and cherry-pickthe left branch covers most cases and needs no stash at all

Step 2 β€” Use a stash when the switch is refused Jump to heading

git switch other-branch
# error: Your local changes to the following files would be overwritten by checkout
git stash push -u -m 'refund window work, moving to the right branch'
git switch other-branch
git stash pop
# Verification: the changes are present on the intended branch
git status --short
git stash list        # empty, if the pop succeeded

If the pop conflicts, the entry survives and the conflict is resolvable β€” the procedure is in resolving conflicts when popping a stash.

Step 3 β€” Move commits that landed on the wrong branch Jump to heading

If you committed before noticing, the commits themselves have to move.

# Where they should have gone
git switch -c feat/PAY-812-refund-window
# Remove them from the branch they landed on
git switch main
git reset --keep origin/main
# Verification: main matches the remote, the commits are on the new branch
git log --oneline -1 main
git log --oneline origin/main..feat/PAY-812-refund-window

--keep rather than --hard is deliberate: it refuses rather than discarding if there are uncommitted changes that would be lost, which is exactly the safety you want while moving things around. The distinction between the reset modes is covered in when to use git revert vs git reset.

Moving two commits off the default branchThe commits were made on the default branch by mistake. Creating a branch at the current tip keeps them, and resetting the default branch back to its remote tip removes them from it without touching the objects.branch first, then resetbefore: mainABC1C2after: mainABafter: featureBC1C2nothing is deleted β€” main's ref moves back and the feature branch holds the commits

Step 4 β€” Split changes that belong on two branches Jump to heading

Frequently the work contains two unrelated things, and only one of them belongs here.

# Stash only the paths that belong elsewhere
git stash push -m 'unrelated config change' -- config/services.yaml
# Commit what remains on this branch, then move the stash
git commit -am 'feat(payments): clamp the refund window'
git switch -c chore/config-tidy origin/main
git stash pop
# Verification: each branch contains only its own change
git diff --stat origin/main
git diff --stat origin/main feat/PAY-812-refund-window
# For a split inside a single file, stage hunks selectively
git add -p src/payments/refund.ts
git commit -m 'feat(payments): clamp the refund window'
git stash push -m 'the rest, for another branch'

SAFETY WARNING β€” never use git checkout -- . or git restore . to β€œclean up” while sorting this out. Both discard uncommitted changes immediately and there is no reflog for content that was never committed. If you need a clean tree, stash it β€” the stash is recoverable and a discard is not.

Step 5 β€” Verify both branches before moving on Jump to heading

# The branch you moved away from should be untouched
git diff --stat origin/main main
# The branch you moved to should have exactly the intended work
git log --oneline origin/main..HEAD
git status --short
# And nothing should be left behind on the stack
git stash list
The safe order for moving workCheck what is modified, create or switch to the target branch carrying the changes, commit there, then verify that the original branch is unchanged and the stash stack is empty. Each check is one command and catches a different way this goes wrong.Check statuswhat is modifiedSwitch or stashcarry the changesCommit thereon the right branchVerify bothand the stack is emptythe last box catches the half-moved state that otherwise surfaces days later

Validation checklist Jump to heading

Frequently Asked Questions Jump to heading

Why did the switch work without a stash? Jump to heading

Because Git only refuses when carrying the changes would be ambiguous β€” that is, when the files you modified differ between the two branches. Creating a new branch from the current commit never has that problem, which is why the simple case works so often and surprises people who expect to need a stash.

Can I move work to a branch that does not exist yet on the remote? Jump to heading

Yes, and it is the common case: git switch -c creates it locally and git push -u origin HEAD publishes it. Doing the push immediately is worth the habit, because it converts local-only work into something with a backup.

What if the work spans a commit that was already pushed? Jump to heading

Then moving it means rewriting published history, which needs the care described in safe git rebase -i for shared branches. Often the better answer is to leave the commit where it is and cherry-pick it onto the right branch, accepting that it exists in both places until one is cleaned up.