Skip to content

feat(git): VS Code-style branch sync control#3075

Open
TheIcarusWings wants to merge 1 commit into
pingdotgg:mainfrom
TheIcarusWings:t3code/git-sync-control
Open

feat(git): VS Code-style branch sync control#3075
TheIcarusWings wants to merge 1 commit into
pingdotgg:mainfrom
TheIcarusWings:t3code/git-sync-control

Conversation

@TheIcarusWings

@TheIcarusWings TheIcarusWings commented Jun 13, 2026

Copy link
Copy Markdown

What

Adds a VS Code-style ahead/behind sync control next to the branch in the composer toolbar, plus the standalone git RPCs behind it. Previously there was no visible ahead/behind indicator, no standalone fetch, and no one-click sync — push only existed bundled inside the stacked action.

The control is state-driven:

State Shows Action
Up to date + Fetch Fetch
Ahead ↑N Push
Behind ↓N Pull (--ff-only)
Diverged ⟳ ↓N ↑M Sync → clear "diverged" toast + Rebase & sync
No upstream Publish Push + set upstream

A standalone Fetch button is always present to force-refresh the counts (the server already auto-fetches on a 30s poller; this just bypasses the wait).

How

  • contracts: vcs.fetch / vcs.push / vcs.sync RPCs + a typed GitDivergedError.
  • server: GitVcsDriverCore.fetchCurrentBranch + syncCurrentBranch (fast-forward pull / push / publish chosen by ahead-behind; diverged history → GitDivergedError unless mode:"rebase", which runs git pull --rebase and aborts cleanly on conflict so the tree is never left mid-rebase). The standalone push reuses the exact driver call the stacked action uses, so upstream + push-remote resolution (fork-aware) stays shared. Never force-pushes.
  • client: wsRpcClient vcs.{fetch,push,sync}, action-manager operations, and useVcs{Fetch,Push,Sync}Action hooks.
  • web: new GitSyncControl wired into the branch toolbar (reuses the existing status subscription — no extra WS traffic).

Hardening

Extracts RPC_REQUIRED_SCOPE into its own module with a completeness test asserting every WsRpcGroup method declares an auth scope — this gate was previously runtime-only (a missing scope threw on a live call, not in CI).

Tests

  • Real-git integration tests for ahead→push, behind→ff-pull, diverged→typed error (clean tree), rebase→push, publish→set-upstream, and fetch.
  • Updated the affected client/web RPC mocks.
  • All 5 UI states manually verified end-to-end in the running app against a scratch repo + bare remote + teammate clone (linear history confirmed after rebase; branch + upstream confirmed after publish).

🤖 Generated with Claude Code


Note

Medium Risk
New git mutating RPCs run real fetch/pull/push/rebase in user workspaces; behavior is covered by integration tests and avoids force-push, but rebase-on-confirm still changes history on the current branch.

Overview
Adds a VS Code-style ahead/behind control beside the composer branch picker: publish, pull, push, one-click sync, and a manual Fetch, driven by existing VCS status (no extra subscription).

Contracts & server: New vcs.fetch, vcs.push, and vcs.sync WebSocket RPCs plus GitDivergedError. GitVcsDriverCore implements fetchCurrentBranch (targeted remote-tracking refresh) and syncCurrentBranch (fetch then ff-pull / push / publish by ahead-behind; diverged history errors unless mode: "rebase", with rebase aborted on conflict). Standalone push maps through the same driver path as stacked actions. Handlers refresh git status after each call.

Client: wsRpcClient, VCS action manager, and useVcs{Fetch,Push,Sync}Action hooks; GitActionsControl treats fetch/push/sync as busy operations.

Hardening: RPC_REQUIRED_SCOPE moves out of ws.ts into rpcRequiredScope.ts with a test that every WsRpcGroup method has a scope (including the new VCS RPCs under orchestration operate).

Tests: Real-git integration coverage for sync paths; mocks updated across client/web tests.

Reviewed by Cursor Bugbot for commit c365aaa. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add VS Code-style branch sync control with fetch, push, and sync RPC endpoints

  • Adds GitSyncControl to the branch toolbar with ahead/behind indicators and buttons for Publish, Pull, Push, Sync, and Fetch, mirroring VS Code's branch sync UX.
  • Implements fetchCurrentBranch, pushCurrentBranch, and syncCurrentBranch in GitVcsDriverCore.ts and GitWorkflowService.ts, covering publish, fast-forward pull, push, and rebase+push flows.
  • Exposes three new WebSocket RPC methods (vcs.fetch, vcs.push, vcs.sync) with contracts defined in packages/contracts/src/git.ts and rpc.ts.
  • Introduces GitDivergedError for diverged branches; the sync UI surfaces this with a secondary "Rebase & sync" action.
  • Moves authorization scope declarations to a shared rpcRequiredScope.ts module with completeness tests.

Macroscope summarized c365aaa.

Adds an ahead/behind indicator with one-click fetch/pull/push/publish/sync
next to the branch in the composer toolbar, plus the standalone RPCs behind it.

- contracts: vcs.fetch / vcs.push / vcs.sync RPCs + GitDivergedError
- server: GitVcsDriverCore.fetchCurrentBranch + syncCurrentBranch (fast-forward
  pull / push / publish chosen by ahead-behind; diverged history -> typed
  GitDivergedError unless mode:"rebase", which runs pull --rebase and aborts
  cleanly on conflict). Standalone push reuses the stacked-action driver call so
  upstream + push-remote (fork) resolution stays shared.
- client: wsRpcClient vcs.{fetch,push,sync}, action-manager ops, action hooks
- web: GitSyncControl component wired into the branch toolbar
- tests: real-git integration tests for ahead/behind/diverged/rebase/publish/fetch

Also extracts RPC_REQUIRED_SCOPE into its own module with a completeness test
asserting every WsRpcGroup method declares an auth scope, so a missing scope
fails in tests instead of at runtime.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 692ab594-1a9b-4145-91b7-c8464b7fe4e6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Jun 13, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c365aaa. Configure here.

loading: { title: "Fetching..." },
success: () => ({ title: "Up to date", description: "Refreshed remote-tracking refs." }),
error: (err) => ({ title: "Fetch failed", description: errorMessage(err) }),
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fetch toast claims up to date

Medium Severity

The fetch action’s success toast always uses the title “Up to date”, even though vcs.fetch only refreshes remote-tracking refs and does not change the local branch. After a fetch, ahead/behind counts may still show the branch is behind or ahead, so the toast text contradicts the sync control state.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c365aaa. Configure here.

environmentId={environmentId}
cwd={branchCwd}
status={branchStatusQuery.data}
/>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Branch picker ignores sync busy

Medium Severity

GitSyncControl disables its buttons while fetch, push, pull, or sync runs via useSourceControlActionRunning, but the adjacent branch combobox only respects isBranchActionPending from branch switch transitions. Users can checkout or create refs while a toolbar sync operation is still in flight on the same cwd.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c365aaa. Configure here.

@macroscopeapp

macroscopeapp Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new user-facing feature (VS Code-style branch sync control) with new UI components, new RPC endpoints, and new backend git operations. New features introducing user-facing behavior warrant human review. Additionally, there are unresolved review comments about misleading toast text and potential race conditions.

You can customize Macroscope's approvability policy. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant