| name | rebase-conflict |
| description | Systematic approach to rebasing a stale PR branch onto a diverged upstream main — from PRs |
Rebase Conflict Resolution
Systematic workflow for rebasing a stale PR branch when upstream has moved significantly.
Distilled from rebasing two PRs (#38823, #38853) that were each 10+ commits behind
upstream/main.
Pre-flight
unset GITHUB_TOKEN
git fetch upstream main
git merge-base HEAD upstream/main
git log --oneline HEAD..upstream/main | wc -l
git stash push -m "pre-rebase-wip"
Phase 1: Understand the divergence
Before attempting the rebase, understand WHAT changed upstream:
git diff --name-only HEAD..upstream/main -- $(git diff --name-only main...HEAD)
git show upstream/main:<path> 2>/dev/null
Key questions to answer:
- Was any code EXTRACTED to a new file (god-file split)?
- Were functions REORDERED (e.g., native-first vs text-first ordering)?
- Were new functions ADDED in the same region as your additions?
Phase 2: Trial merge
git stash push -m "pre-rebase-check"
git rebase upstream/main
git rebase --abort
Read each conflict carefully. Three common patterns:
Pattern A: Parser extraction
Upstream extracted inline argument-parser code into hermes_cli/subcommands/<name>.py.
Your branch adds flags to the old inline location.
Resolution: Accept upstream's extraction. Move your new flags to the subcommands file.
doctor_parser.add_argument("--json", ...)
doctor_parser.add_argument("--verbose", ...)
build_doctor_parser(subparsers, cmd_doctor=cmd_doctor)
Pattern B: Function reordering
Upstream reordered branches within a function (e.g., capability check before fallback
check). Your branch added log calls in the OLD order.
Resolution: Preserve upstream's ordering. Transplant your log calls into the
correct branches without reordering them.
supports = _lookup_supports_vision(provider, model, cfg)
if supports is True:
return "native"
if supports is False:
return "text"
if _explicit_aux_vision_override(cfg):
return "text"
return "text"
Pattern C: New function in the same region
Upstream added a function between two of yours, or your branch added functions in
a region where upstream also added code.
Resolution: Keep BOTH functions. Order: upstream additions first, then your
additions, respecting their logical grouping.
Phase 3: Execute the rebase
git rebase upstream/main
grep -n '<<<<<<< HEAD\|=======\|>>>>>>>' <file>
git add <file>
git rebase --continue
git rebase --skip
Phase 4: Restore working changes
After successful rebase:
git stash pop
Phase 5: Verify
python3 -c "
import ast
for f in ['file1.py', 'file2.py']:
ast.parse(open(f).read())
print(f'{f}: OK')
"
uv run pytest tests/ -q -m "not integration" -o "addopts="
git diff upstream/main --stat
git log --oneline upstream/main..HEAD
Common pitfalls
| Pitfall | Fix |
|---|
if moa_config is None: without body | Upstream restructured conditionals — read full upstream version, restore the body |
Closing >>>>>>> marker left behind | grep -rn '>>>>>>>' and remove |
| Stash conflicts after rebase | Resolve by hand: keep upstream code, layer your fixes |
Forgetting the --force-with-lease | git push --force-with-lease origin <branch> |
Post-rebase check list
Related patterns
- [[review-response]] — systematic approach to receiving and acting on review feedback
- [[credential-leak-audit]] — finding and fixing credential leaks in output