Emmanuel Corels
← Blog
Product Engineering

Move uncommitted work off the wrong Git branch

Preserve staged, unstaged and untracked changes while creating the correct branch—and handle the harder case where that branch needs a different base.

By Emmanuel Corels

You start a feature, then notice the prompt still says main. If the new branch should begin at the current commit, the fix is pleasantly small: create and switch branches. Your working tree and index belong to the worktree, so creating a branch does not discard them.

Inventory the work before moving anything

git status --short --branch
git diff --stat
git diff --cached --stat
git ls-files --others --exclude-standard

This separates unstaged tracked changes, staged changes and untracked files. Ignored files are intentionally absent; if a generated or secret file matters to the local workflow, record it without committing it.

The direct move when the current commit is the right base

git switch -c feature/data-cleanup
git status --short --branch

git switch -c creates the branch at the current HEAD and switches to it transactionally. Staged changes remain staged, unstaged changes remain unstaged, and untracked files remain in the directory. Git’s documentation states that switching does not require a clean working tree unless updating files would lose local changes.

Now review and commit deliberately:

git diff
git diff --cached
git add -p
git diff --cached
git commit -m "Normalize imported transaction fields"

Do not commit on main merely to make the move

A temporary commit can be recovered, but it adds unnecessary history surgery. Creating the branch first is clearer. Likewise, a stash is not needed when the desired branch begins at the current commit.

When the destination must start from another base

Suppose the work began on main but should be based on the latest origin/release/2.x. Switching may be refused if the destination changes files you modified. Preserve all three classes of work:

git stash push --include-untracked   -m 'move data-cleanup work to release/2.x'
git fetch origin
git switch -c feature/data-cleanup origin/release/2.x
git stash apply

Use apply first rather than pop. The stash remains available until you verify the result. If conflicts occur:

git status
git diff --name-only --diff-filter=U
# resolve each file
git add path/to/resolved-file
git diff --cached
git stash drop

Drop only the specific stash entry after tests and inspection. If several stashes exist, identify it with git stash list and reference the exact entry.

Preserve staged versus unstaged intent

A normal stash may not restore index state exactly as expected. If the staged grouping matters, apply with:

git stash apply --index stash@{0}

If it cannot reinstate the index cleanly, Git reports conflicts. The file contents remain recoverable; rebuild staging with git add -p rather than forcing the state.

If you already committed on the wrong branch

Create the desired branch at the current commit before moving the original branch:

git switch -c feature/data-cleanup
git log --oneline --decorate -3
git switch main
git reset --hard origin/main

The final reset is appropriate only after confirming feature/data-cleanup points to the accidental commit, origin/main is the intended target, and main has no other local work. A safer audit trail is:

git branch rescue/main-before-reset main
git fetch origin
git log --left-right --graph --oneline main...origin/main

Verify the new branch owns the work

git branch --show-current
git status --short
git diff --check
git diff --cached --check
git log -1 --oneline --decorate

Run the project’s tests before the first commit. Then set the upstream only when you publish:

git push -u origin feature/data-cleanup
SituationPreferred move
Uncommitted work; same basegit switch -c new-branch
Uncommitted work; different baseStash including untracked files, switch from intended base, apply
Committed locally on wrong branchCreate desired branch at current commit, then repair original branch
Destination already exists and overlapsStash, switch normally, apply and resolve

A branch is a movable name for a commit. Your uncommitted changes live in the index and working tree, which is why creating the right name first is usually enough.

Sources: the solved Stack Overflow question (CC BY-SA), Git’s official git-switch documentation, and the git-stash reference.

Primary source: Review the official reference ↗