git.tools / guides

Pushed to the wrong branch? Here's how to fix it

Committed work onto main that belonged on a feature branch — and maybe pushed it too. Move it with cherry-pick, then clean up the wrong branch the safe way.

Last updated September 18, 2026 · 7 min read

It happens to everyone: you were on main instead of your feature branch, committed three times, maybe even pushed. The fix has two halves — get the work onto the right branch, then clean up the wrong one — and the order matters. Work first, cleanup second.

TL;DR:

# 1. Move the work to the right branch
git switch -c right-branch        # or: git switch right-branch
git cherry-pick <sha>             # each misplaced commit, oldest first
git push -u origin right-branch

# 2. Clean the wrong branch — which command depends on whether you pushed.
#    Keep reading before running anything destructive.

First: two questions that decide everything

Did you push? If the commits never left your machine, this is a two-minute fix with zero risk.

Does anyone else pull the wrong branch? If yes (and for main, the answer is always yes), the cleanup half must not rewrite history. That means revert, not reset.

Not pushed yet — easy mode

The commits exist only in your clone, so you're free to move things around. List the culprits:

git log --oneline -5

Create the right branch and pull the commits over:

git switch -c feature/the-right-branch
git cherry-pick <oldest-sha> <middle-sha> <newest-sha>

Now put the wrong branch back where the remote left it. Since you never pushed, origin/<branch> still points at the pre-mistake state:

git switch main
git reset --hard origin/main

Done. The work lives on the right branch, the wrong branch looks like nothing happened, and nobody else was ever involved.

Not even committed? Even easier — uncommitted changes travel with you when you switch branches (as long as they don't collide with differences between them). Just git switch -c feature/the-right-branch and commit there. Or git stash, switch, git stash pop.

A softer variant some prefer: instead of cherry-picking, undo the commits on the wrong branch while keeping their changes staged — git reset --soft HEAD~3 — then git stash, switch to the right branch, git stash pop, and commit fresh. Same destination; the cherry-pick route just preserves the original commit messages and authorship metadata without extra steps, which is why it's the one I'd default to.

Already pushed — step 1: rescue the work first

Same cherry-pick move as above, then push the right branch:

git switch -c feature/the-right-branch origin/main   # wherever it should base off
git cherry-pick <sha>...
git push -u origin feature/the-right-branch

Now your work exists in two places, and that's deliberate: you can't lose it during cleanup. Only now touch the wrong branch.

Already pushed — step 2: clean the wrong branch

Two ways. Pick based on that second question.

The safe way: revert. If anyone could have pulled — and on shared branches, assume someone did — append commits that undo yours:

git switch main
git revert <newest-sha> <middle-sha> <oldest-sha>
git push

Revert creates new commits that apply the exact inverse of yours. History moves forward, nobody's clone breaks, and it works even on branches where force pushes are blocked by branch protection. The log gets a little noisy — that's the price of not ruining a teammate's afternoon.

The fast way: reset + force-push. Only if you're certain nobody pulled — a branch only you use, or a push that happened thirty seconds ago. Before resetting, look at exactly what's about to be erased: git log --oneline -5 and confirm every commit above your reset point is genuinely yours and genuinely misplaced. Then:

git switch main
git reset --hard HEAD~3        # or the SHA just before your commits
git push --force-with-lease

--force-with-lease (never bare --force) refuses the push if the remote moved since your last fetch — your last guard against clobbering someone's unseen work. If the push is rejected because the branch is protected, take the hint and use revert instead.

The difference in one line: revert appends, reset rewrites. Appending is always safe to share; rewriting is only safe when history is exclusively yours. When you're genuinely unsure which situation you're in, that's the answer: you're in the revert situation.

When your commits aren't the tip anymore

Sometimes you discover the mistake late: you pushed to main, and teammates have since committed on top of your misplaced work. This changes the cleanup, not the rescue — cherry-pick to the right branch works exactly the same regardless of where your commits sit.

But reset + force-push is now off the table. Resetting to before your commits would orphan your teammates' commits too, and force-pushing that onto a shared branch turns your small mistake into everyone's incident. Revert is the only clean move — and it handles buried commits fine, because revert works by SHA, not by position:

git revert <sha-of-your-commit-1> <sha-of-your-commit-2>
git push

Their work stays, yours gets inverted, history keeps moving forward.

The git.tools way

Roll the wrong branch back with Time Travel

Point at the commit right before your accidental ones. git.tools opens a pull request that restores the branch to exactly that state — reviewed, no force push, no awkward message about rewriting main.

Open Time Travel →

One wrinkle for later

If you cleaned the wrong branch with a revert and the right branch eventually merges into it, git may get confused: the merge contains changes the revert "cancelled," and you can see odd conflicts or silently missing changes. The fix when it happens is as weird as it sounds — revert the revert commit on the wrong branch, then merge. Same trap as undoing a merge, which has its own guide.

Common questions

Cherry-pick or merge — which should I use to move the commits?

Cherry-pick. Merging the wrong branch into the right one drags in everything on the wrong branch, not just your misplaced commits. Cherry-pick moves exactly the commits you name, oldest first, nothing else.

Can I cherry-pick a whole range at once?

Yes — if your misplaced commits are contiguous, git cherry-pick A^..B picks everything from A through B in order (the ^ includes A itself). Handy when "three commits" turns out to be nine.

The wrong branch already has a PR open from it. What happens to that?

The PR shows whatever its source branch contains. If you revert on the branch, the PR grows revert commits (noisy but coherent); if you force-push the branch, the PR updates to the cleaned history. Either way, then close or retarget the PR as needed — and if any misplaced commit is inside a PR's history on GitHub, its refs/pull/* copy lingers server-side, which matters for secrets but not for ordinary code.

I pushed to main directly and branch protection didn't stop me. Is that bad?

It means direct pushes to main are allowed in your repo settings — the git part is fixable with a revert as above, but consider tightening the branch rules afterwards so the next accident bounces off.

How do I stop doing this entirely?

Two habits: run git branch --show-current (or keep the branch in your shell prompt) before committing, and protect shared branches so a mistaken git push to main is rejected instead of published. The second one turns a cleanup job into a harmless error message.

The commits were someone else's that I pushed to the wrong place. Same fix?

Same fix, plus a courtesy: tell them before you revert or force-push, since their local branch will still contain the commits and a confused re-pull can resurrect them.