On a branch drifted behind a busy main, git rebase origin/main conflicts on the first commit and again on each remaining one — 16 instead of one. Rebase an empty branch and replay the work as one uncommitted change.
git checkout branch-to-rebase
git fetch --all
git merge-base branch-to-rebase origin/main # last commit before the branch's own work
Reset to it: the branch’s differences return to the working tree, unstaged:
git reset f9fb326cb6cd58e0f31b433389b4a76f60319db1
Stash it; the rebase has nothing to conflict over:
git stash
git rebase origin/main # Successfully rebased and updated refs/heads/branch-to-rebase
git stash pop # conflicts now appear exactly once
Resolve, commit, push:
git commit
git push --force
Two side effects: a squash rebase (one commit), and the original branch is gone — use git checkout -b clean-branch origin/main instead of the rebase when it matters.
The two aliases
mb returns the merge-base of the current branch, reset-to-base feeds it to reset:
mb = "!f() { git branch --show-current | xargs git merge-base $1; }; f"
reset-to-base = "!f() { git mb $1 | xargs git reset; }; f"
git mb origin/main # f2732648ef5b6804a63d44f1b498f19ddf01eeb6
git reset-to-base origin/main # reset to that base
Both are in the aliases note with the rest.