Syncing
Keep the stack current when main moves or when you change a lower branch.
Fetch and rebase
arc sync # or: arc sync --push, to push the stack in the same command
Fetches from remote, then brings in what changed there:
- Fast-forwards your local
maintoorigin/main. If your localmainhas commits that aren't on origin, arc leaves it alone. - Fast-forwards any stack branch that a teammate pushed to, so their commits stay in your stack.
- Removes branches whose changes are already in
main, whether the PR was squash-merged, rebased, or merged with a merge commit.
Then it runs a cascade rebase bottom-up through the stack:
- Rebase
feat/authonto the new tip ofmain - Rebase
feat/apiontofeat/auth - Rebase
feat/uiontofeat/api
If everything rebases cleanly, arc exits 0. Run arc push to update the remote.
arc push refuses to overwrite a remote branch that has commits your local branch never had, such as a teammate's commit pushed after your last sync. Run arc sync again, then push.
Uncommitted changes
arc sync, arc rebase, arc drop, and arc land check out each branch they restack, so they stop before changing anything when you have uncommitted changes:
error: uncommitted changes in src/api.py
hint: commit or stash them first: git stash && arc sync && git stash pop
Conflict recovery
When a conflict occurs, arc pauses and tells you what to fix:
✗ Conflict in feat/api
Conflicting files:
src/api.py
Resolve the conflict, then run:
arc rebase --continue
To undo and return to the pre-sync state:
arc rebase --abort
Arc exits with code 3. The branches above the conflict are untouched; the branches below are already rebased.
To continue:
- Open the conflicting file and fix the conflict markers (
<<<<<<<,=======,>>>>>>>) - Stage the resolution:
git add src/api.py - Run
arc rebase --continue
Arc finishes the rebase of feat/api, then cascades to feat/ui and any branches above. If another conflict appears, arc pauses again.
To abort:
arc rebase --abort
Rolls back every branch to exactly where it was before arc sync started — including branches that had already rebased cleanly during this run.
Fine-grained rebase
Rebase only part of the stack without syncing from remote:
arc rebase # cascade the entire stack (no fetch)
arc rebase --upstack # current branch and everything above it
arc rebase --downstack # current branch and everything below it
These are useful when you've amended a commit locally and want to restack without running a full sync.
Restack a single branch
arc restack feat/api
Rebases feat/api onto its parent branch in the stack without touching the branches above it. Faster than a full rebase when only one branch needs updating.
Conflict prediction
Before syncing, preview what would happen:
arc sync -n
The dry-run output shows the rebase plan and warns if adjacent branches touch the same files — a hint that a conflict is likely, not a guarantee.
Repeated conflicts and rerere
arc setup enables git rerere, which records how you resolved a conflict and replays the resolution automatically if the same conflict appears again. This means an arc rebase --abort followed by a retry, or a second sync after fixing the same upstream change, rarely needs you to resolve the same conflict twice.
If rerere was not set up automatically:
git config --global rerere.enabled true