Skip to content

fix(vcs): reflect external git changes in status via .git watcher#2987

Open
denniskasper wants to merge 1 commit into
pingdotgg:mainfrom
denniskasper:fix/vcs-status-git-watcher
Open

fix(vcs): reflect external git changes in status via .git watcher#2987
denniskasper wants to merge 1 commit into
pingdotgg:mainfrom
denniskasper:fix/vcs-status-git-watcher

Conversation

@denniskasper

@denniskasper denniskasper commented Jun 7, 2026

Copy link
Copy Markdown

What Changed

Added a filesystem watcher on the checkout's git directory in VcsStatusBroadcaster. When HEAD/packed-refs change on disk, it pushes a fresh local status (debounced so one operation = one refresh). It resolves the worktree gitdir when .git is a file, and is ref-counted alongside the existing remote-status poller (torn down with the last subscriber). Includes an end-to-end test.

Why

VCS status was only re-read on window focus/visibilitychange and after app-initiated git actions. So a branch switch or checkout done in a terminal (or another git client) wasn't reflected in the UI until the window regained focus. This is the root cause behind the stale-branch-list symptom in #2926 — the watcher resyncs automatically, so no manual refresh button is needed.

Related to #2926.

UI Changes

No markup change — behavioral. Observable effect: after a terminal git switch, the branch toolbar/list updates on its own instead of only after refocusing the window.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes (N/A — no visual change)
  • I included a video for animation/interaction changes (to attach)

Note

Refresh VCS local status when .git directory changes on disk

  • Adds a filesystem watcher on the repo's .git directory (or linked worktree gitdir) in VcsStatusBroadcaster that triggers refreshLocalStatus when HEAD or packed-refs change.
  • Debounces watch events by 150ms to coalesce rapid bursts (e.g. during a git checkout).
  • The watch fiber is started alongside the existing remote polling fiber on first subscriber and interrupted when subscriber count reaches zero.
  • Handles linked worktrees by reading the .git file to resolve the actual gitdir path.
  • Behavioral Change: ActiveRemotePoller now tracks two fibers; both are interrupted on teardown instead of only the remote polling fiber.

Macroscope summarized 9cc0017.

vcs-status-live-update-external-git-switch.webm

Note

Medium Risk
Adds long-lived fs.watch fibers tied to VCS status streaming lifecycle; incorrect gitdir resolution or watch teardown could miss updates or leak watchers, but scope is limited to local status refresh.

Overview
VcsStatusBroadcaster now watches the checkout’s git metadata directory (.git or a linked worktree gitdir) and calls refreshLocalStatus when HEAD or packed-refs change on disk, so terminal git switch / checkout updates the UI without waiting for window focus.

Watch events are debounced (150ms) to collapse multi-file git writes into one refresh. The watch runs in a second fiber started with the existing remote poller on first streamStatus subscriber; both fibers are interrupted when the last subscriber disconnects.

Adds a live it.live test that rewrites .git/HEAD in a temp repo and asserts a localUpdated stream event.

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

VCS status was only re-read on window focus / visibilitychange and after app-initiated git actions, so a branch switch or checkout made in a terminal (or another git client) was not reflected in the UI until the window regained focus. Add a filesystem watcher on the checkout's git directory (HEAD / packed-refs, resolving the worktree gitdir when .git is a file) that pushes a fresh local status on change, debounced so one operation triggers a single refresh. The watcher is ref-counted alongside the existing remote-status poller and torn down with the last subscriber.

Related to pingdotgg#2926.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 7, 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: 34c47830-df69-4aae-b602-4aae8b5c0c34

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:M 30-99 changed lines (additions + deletions). labels Jun 7, 2026
@denniskasper denniskasper marked this pull request as ready for review June 7, 2026 14:44
@macroscopeapp

macroscopeapp Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Introduces new runtime behavior by adding filesystem watchers on .git directory to detect external git changes. New features that add continuous background behavior (file watching with side effects) warrant human review.

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: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