Skip to content

fix(server): a zero Git fetch interval also stops the status upstream fetch - #33845

Open
chomamateusz wants to merge 1 commit into
pingdotgg:mainfrom
chomamateusz:fix/status-fetch-honours-interval
Open

chomamateusz wants to merge 1 commit into
pingdotgg:mainfrom
chomamateusz:fix/status-fetch-honours-interval

Conversation

@chomamateusz

@chomamateusz chomamateusz commented Nov 10, 2026 •

Copy link
Copy Markdown

Problem

Settings ‚Üí Source Control ‚Üí Git fetch interval says "Set to 0 to avoid automatic Git prompts". With 0, VcsStatusBroadcaster skips the upstream fetch (poller, getStatus, refreshStatus; #13253 added the window-focus half for #13235). The Git driver core still fetches on its own: refreshStatusUpstreamIfStale runs git --git-dir <common-dir> fetch --quiet --no-tags --no-auto-gc <remote> from every statusDetails() call and from statusDetailsRemote() whenever the caller does not pass refreshUpstream: false, with a 15 s success TTL and a failure backoff capped at 15 minutes.

Paths that reached that fetch with the interval at 0 (line numbers on main before this change):

  • apps/server/src/vcs/GitVcsDriverCore.ts:2392 statusDetails(cwd) refreshes unconditionally; :2405 statusDetailsRemote(cwd, options) refreshes unless options.refreshUpstream === false.
  • apps/server/src/git/GitManager.ts:1463 remoteStatusResultCache ‚Üí readRemoteStatus(cwd) with no options, reached by GitManager.remoteStatus(input) without options (:2433) and GitManager.status (:2437, via GitWorkflowService.status :324).
  • apps/server/src/git/GitManager.ts:1959 buildCompletionToast, :2294 runPrStep, :2873 preparePullRequestThread, :2894 ensureExistingWorktreeUpstream, :2948 reuseExistingWorktree, :3153 runStackedAction ‚Üí gitCore.statusDetails.
  • apps/server/src/vcs/GitVcsDriverCore.ts:2669 pushCurrentBranch ‚Üí statusDetails (from GitManager.pushCurrentBranch :747, runStackedAction :3282, SourceControlRepositoryService.publishRepository :506).
  • apps/server/src/serverRuntimeStartup.ts:209 auto-pull projects at startup; apps/server/src/sourceControl/SourceControlRepositoryService.ts:495 publishing a repository without commits.

Environment where it shows: a project whose origin is an SSH remote and whose key lives in a GUI SSH agent that asks for approval per use (1Password SSH agent, macOS). Each attempt raises an approval dialog attributed to T3 Code; unattended attempts time out after 60 s and are retried on the backoff schedule. The agent's log on the reporting machine shows 25 to 63 unattended prompts per day with the interval at 0. #13912 (accepted) describes the same fetch retrying every 15 minutes against a macOS Keychain prompt for an HTTPS remote.

Expected: with the interval at 0, no automatic git fetch runs anywhere in the server, as the setting copy promises and as #13253 established for the window-focus path.

Change

refreshStatusUpstreamIfStale returns before spawning Git when the configured automatic fetch interval is zero. VcsAutomaticFetchInterval (the Context.Reference holding the settings-backed interval) and its layer move from VcsStatusBroadcaster.ts into apps/server/src/vcs/VcsAutomaticFetchInterval.ts, so the driver core can read the interval without importing the broadcaster (which would cycle through GitWorkflowService and GitManager). server.ts provides the layer once at the root of layerRuntimeDependencies: GitVcsDriver.layer is memoised and some of its build sites live outside server.ts (orchestration-v2/runtimeLayer.ts, per-connection in ws.ts), so the interval has to be in context before the first build captures it. The broadcaster's own provision becomes redundant and is removed. Every non-zero interval keeps today's behaviour: same cache, same timeouts, same backoff.

Behaviour note for maintainers: with the interval at 0, the implicit upstream refresh inside git action flows (runStackedAction, runPrStep, worktree reuse) is skipped too, so a create_pr action decides wantsPush from the last known origin/<branch>. Push, pull, explicit fetch, PR checkout and thread launch fetches are unaffected (they do not go through refreshStatusUpstreamIfStale).

Scope and approval

One underlying defect: the 0 setting is honoured by the broadcaster but not by the driver core's staleness fetch. The intended behaviour is already established by the triaged issue #13235 and its fix #13253 ("a zero Git fetch interval also stops the fetch on window focus"); this change closes the remaining paths of the same defect and removes the retry loop of #13912 for users who set the interval to 0. No new behaviour, no new setting, no change to defaults.

Verification

  • New test in apps/server/src/vcs/GitVcsDriverCore.test.ts, "does not fetch for status when the automatic fetch interval is zero", next to "does not fetch for status when the branch tracks a local branch": a repo whose branch tracks a bare origin, driver built with the interval at zero, statusDetails then statusDetailsRemote; asserts upstreamRef === origin/<branch> and no fetch spawn. Against main's GitVcsDriverCore.ts it fails with expected [ [ '--git-dir', ‚Ķ(7) ] ] to deeply equal [] (one fetch spawned); with the change it passes. The existing case "can read cached remote divergence without fetching upstream" keeps covering the default interval (one fetch).
  • pnpm exec vp test run src/vcs/GitVcsDriverCore.test.ts (246 tests; two pre-existing cases need an unsandboxed run and a canonical TMPDIR on this machine, identical on main), src/vcs/VcsStatusBroadcaster.test.ts 26/26.
  • node scripts/check-changed.ts: format, lint, knip 1/2 and 2/2, graphql (apps/server), typecheck (3 packages), test (3 files, 274 tests) all pass.
  • Not checked yet: a running desktop build with the interval at 0 against the 1Password SSH agent. The build with this change is being installed on the reporting machine; the before/after count of agent prompts will be added here. Also not checked: Windows, Linux desktop.

Code written with Claude Opus 5.5 in Claude Code (T3 Code harness); reviewed by Claude Opus 5.5 and GPT-6.1 Sol.

… fetch

Settings → Source Control → Git fetch interval = 0 promises no automatic Git
prompts. VcsStatusBroadcaster honours it (pingdotgg#13253 for pingdotgg#13235), but the Git
driver core still fetched on its own: refreshStatusUpstreamIfStale runs
`git fetch --quiet --no-tags --no-auto-gc <remote>` from every statusDetails()
call and from statusDetailsRemote() unless the caller passes
refreshUpstream: false, with a 15 s success TTL and a failure backoff capped at
15 minutes. GitManager.status / remoteStatus without options, the git action
flows, startup auto-pull and repository publishing all reached it. With an SSH
remote and a GUI SSH agent every attempt raised an approval prompt although the
setting was 0 (pingdotgg#13912 describes the same loop against a Keychain prompt).

refreshStatusUpstreamIfStale now returns before spawning Git when the
configured interval is zero. VcsAutomaticFetchInterval and its settings-backed
layer move into their own module so the driver core can read them without
importing the broadcaster, and server.ts provides the layer at the root of the
runtime dependencies so the memoised GitVcsDriver.layer captures it wherever it
is first built. Non-zero intervals keep the same cache, timeouts and backoff.

Test: GitVcsDriverCore.test.ts "does not fetch for status when the automatic
fetch interval is zero" (fails on main: one fetch spawned).
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Nov 10, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at f21bb9f

Macroscope's review found this PR approvable — Git status refresh now honors a zero automatic-fetch interval instead of contacting the upstream remote. The existing default remains unchanged, and the change is limited to suppressing automatic fetch activity.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The server now provides the VCS automatic-fetch interval through runtime dependencies. Git status checks skip upstream refresh when the configured interval is zero. The tests verify that status methods still report the upstream ref without starting a fetch.

Changes: VCS automatic-fetch interval

Layer / File(s) Summary
Define and provide the fetch interval
apps/server/src/vcs/VcsAutomaticFetchInterval.ts, apps/server/src/server.ts, apps/server/src/vcs/VcsStatusBroadcaster.ts, apps/server/src/vcs/VcsStatusBroadcaster.test.ts
A dedicated context reference resolves the interval from server settings and falls back to the default on failure. The server provides its layer through runtime dependencies. The broadcaster and its test use the dedicated module.
Apply the interval to Git status refresh
apps/server/src/vcs/GitVcsDriverCore.ts, apps/server/src/vcs/GitVcsDriverCore.test.ts
The driver skips upstream refresh when the interval is zero. The test checks that both status methods return the upstream ref without spawning a fetch.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Possibly related issues

Possibly related PRs

  • pingdotgg/t3code#28577: Its checkout refresh logic reads status after upstream fetches, so it is connected to the changed status-fetch behavior.
  • pingdotgg/t3code#13812: It changes the command used by background status fetches, which this PR may prevent from starting when the interval is zero.

Suggested labels: bugfix

Suggested reviewers: juliusmarminge, macroscopeapp

Merge Risk: Minimal · up to f21bb

The configured zero interval reaches WebSocket status checks, so this review found no remaining issue that should block merging.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title clearly identifies the fix: a zero Git fetch interval now prevents status checks from fetching upstream.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The description covers the problem, expected behavior, change, scope and approval rationale, and focused verification. It also states which checks remain outstanding.
Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between f12bb62 and f21bb9f.

Files selected for processing: 6

  • apps/server/src/server.ts
  • apps/server/src/vcs/GitVcsDriverCore.test.ts
  • apps/server/src/vcs/GitVcsDriverCore.ts
  • apps/server/src/vcs/VcsAutomaticFetchInterval.ts
  • apps/server/src/vcs/VcsStatusBroadcaster.test.ts
  • apps/server/src/vcs/VcsStatusBroadcaster.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

This branch has not been deployed

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

Labels

size:M 30-99 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