Skip to content

Redesign sidecar sync: baseline bootstrap + incremental patch#339

Draft
michael-webster wants to merge 1 commit into
mainfrom
webster/sync-redesign
Draft

Redesign sidecar sync: baseline bootstrap + incremental patch#339
michael-webster wants to merge 1 commit into
mainfrom
webster/sync-redesign

Conversation

@michael-webster
Copy link
Copy Markdown
Contributor

Summary

Replaces the current sync mechanism (merge-base recalculation + GitHub clone on every first sync) with a two-phase design:

  • Bootstrap (sidecar setup or stale baseline): clones from GitHub if workspace absent, otherwise git fetch; checks out exact local HEAD when pushed or merge-base otherwise; applies a patch of all local changes; stores BaselineRef + BaselineBranch
  • Incremental sync (sidecar sync, same branch, valid baseline): generates git diff <BaselineRef> --binary locally, resets sidecar to BaselineRef, applies patch — no GitHub access needed after initial setup

Staleness detection re-bootstraps automatically when the branch changes, no baseline is stored, or BaselineRef is no longer an ancestor of HEAD (rebase/force-push).

Also fixes MergeBase() fallback: was returning git rev-parse origin/HEAD (the remote tip, potentially ahead of local HEAD); now correctly uses git merge-base HEAD origin/HEAD.

Remote commands use sh -c "cd <path> && git ..." instead of git -C which is unavailable on the sidecar's older git version.

Changes

  • internal/sidecar/active.go — add BaselineRef, BaselineBranch fields
  • internal/gitutil/gitutil.go — add HeadRef, IsAncestor; fix MergeBase fallback
  • internal/sidecar/sync.go — replace syncWorkspace/Sync with Bootstrap/Sync; remove errApplyFailed retry logic
  • internal/cmd/sidecar.gosidecarSetupSync calls Bootstrap; sync command passes cwd
  • internal/sidecar/sync_test.go — updated for new behaviour
  • acceptance/sidecar_test.go — sync flag test now runs from a git repo

Test plan

  • All unit and acceptance tests pass (go test -race ./...)
  • E2E script (dev-utils/e2e-sync.sh) passes all 4 scenarios on a live sidecar:
    • Fresh bootstrap (no baseline) → clone/fetch + patch applied
    • Incremental sync (same branch) → patch only, no re-clone
    • Branch switch → re-bootstrap triggered
    • Stale baseline (simulated rebase) → re-bootstrap triggered

🤖 Generated with Claude Code

Replaces the merge-base-recalculation-on-every-sync approach with a
two-phase design that is more robust and GitHub-independent after setup.

Bootstrap (sidecar setup / stale baseline):
- Clones from GitHub if workspace absent, otherwise git fetch to update
- Checks out exact local HEAD if branch is pushed, merge-base otherwise
- Applies a patch covering all local changes from the checkout point
- Stores BaselineRef + BaselineBranch in sidecar state

Incremental sync (sidecar sync, same branch, valid baseline):
- Generates git diff <BaselineRef> --binary locally
- Resets sidecar to BaselineRef, applies patch — no GitHub access needed

Staleness detection re-bootstraps automatically when:
- No baseline stored (first sync after create)
- Branch changed since last bootstrap
- BaselineRef is no longer an ancestor of HEAD (rebase/force-push)

Also fixes MergeBase() fallback: was returning git rev-parse origin/HEAD
(the remote tip, potentially ahead of local HEAD); now uses
git merge-base HEAD origin/HEAD for the actual common ancestor.

Remote commands use sh -c "cd <path> && git ..." to support the
sidecar's SSH server without requiring git -C (unavailable on old git).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@michael-webster michael-webster marked this pull request as draft May 18, 2026 20:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant