Rebase — Rebase, Fix Conflicts, Push
Rebase the current branch onto the base branch (default: main), resolve any merge conflicts, and force-push.
Steps
1. Determine Base Branch
- If
$ARGUMENTScontains a branch name, use it as the base. - Otherwise, default to
main.
2. Pre-check Working Tree
git status --porcelain
If output is non-empty, the working tree is dirty. Abort and report to the user:
Working tree has uncommitted changes. Commit or stash before rebasing:
<output of git status --porcelain>
Do NOT auto-stash — too easy to lose work.
3. Fetch Latest
git fetch origin <BASE_BRANCH>
4. Rebase
git rebase origin/<BASE_BRANCH>
5. Handle Conflicts
If the rebase stops with conflicts:
- Run
git diff --name-only --diff-filter=Uto list conflicted files - For each conflicted file:
- Read the file to understand the conflict markers
- Resolve the conflict by understanding both sides (ours = current branch work, theirs = base branch changes)
- Prefer keeping our changes where they don't conflict with upstream intent
- If unsure about a conflict, ask the user
- Stage the resolved files:
git add <resolved-files> - Continue the rebase:
git rebase --continue - If more conflicts appear, repeat steps 1-4
- Max 10 conflict rounds — if still conflicting, abort and ask the user
6. Verify
After successful rebase:
git log --oneline -5
7. Push
Check whether the branch has an upstream:
git rev-parse --abbrev-ref --symbolic-full-name @{upstream} 2>/dev/null
- If the command fails (no upstream): the branch has never been pushed. Use:
git push -u origin "$(git rev-parse --abbrev-ref HEAD)" - If the command succeeds: check ahead/behind state:
ahead=$(git rev-list --count @{upstream}..HEAD) behind=$(git rev-list --count HEAD..@{upstream})- If both
ahead == 0andbehind == 0: nothing to push, skip. - Otherwise (ahead, behind, or diverged):
git push --force-with-lease
- If both
--force-with-lease (not --force) fails safely if someone else pushed to the branch.
8. Report
Rebased onto origin/<BASE_BRANCH>.
Conflicts resolved: <COUNT> files
Push: <force-with-lease | initial -u | skipped (already in sync)>
If the branch already has an open PR, the force-push updates it automatically.