all writing

Rewording Pushed Commits After a Target Branch Merge

If you merged main into your branch and now want to fix commit messages, standard rebase is unusable. Use a worktree + cherry-pick.

2 min read

AI-generated still life of a terminal window with a blinking cursor, in green on a dark charcoal background
On this page

You pushed five commits with terrible messages. Then you merged main into your branch to stay current. Now git rebase -i HEAD~5 wants to process 40 commits, replay a merge, and re-resolve conflicts you already resolved.

Standard advice is “don’t rebase after merging.” That advice is right, and also useless once you’ve already done it. Here’s what I do.

The Approach

Don’t try to untangle the merged history. Build a clean branch in a separate worktree, cherry-pick just your commits onto it, reword there, then force-push over the original.

Step 1: Worktree off the target branch

git worktree add ../repair-shop -b clean-fix origin/sprint-target
cd ../repair-shop

New directory, new branch based on your actual target, zero merge history. Your original working directory is untouched.

Step 2: Cherry-pick your commits

git cherry-pick <oldest-hash>^..<newest-hash>

The ^ includes the oldest commit in the range. If you don’t remember the hashes, git log --oneline in the original directory shows them. You now have your five commits sitting on a clean base.

Step 3: Reword

git rebase -i HEAD~5

Linear history, no merge to replay. Change pick to reword on whichever commits you want to fix, save, edit each message.

Step 4: Replace the remote branch

git push origin clean-fix:story/your-branch-name --force-with-lease

The local:remote syntax pushes your clean branch over the messy remote one. --force-with-lease aborts if someone else pushed since you last fetched. If you need to update your local branch pointer too, switch to it in your original directory and git reset --hard origin/your-branch-name.

Cleanup

cd /path/to/original/repo
git worktree remove ../repair-shop
git branch -D clean-fix

Gotchas

  • Locked worktree error if you try to force-update a branch that’s checked out elsewhere. The local:remote push syntax sidesteps this.
  • Force push is destructive. --force-with-lease helps but isn’t foolproof. Make sure nobody else is on your branch.
  • No merge commits in the result. For most teams that’s a feature. If your team requires merge commits for audit/policy reasons, don’t do this.
  • Uncommitted changes in the original directory stay put. Worktrees are independent.

tl;dr

  • Merging into your branch makes interactive rebase unworkable
  • Worktree + cherry-pick isolates your commits on a clean base where rebase works normally
  • Push with local:remote syntax and --force-with-lease to replace the remote
  • Only do this solo — coordinate before rewriting shared history

written by

Cody Williamson

Senior Software Engineer