Skip to content

feat(watch): live-refresh on external .git changes + fetch-on-focus#7

Merged
jcardonne merged 1 commit into
mainfrom
feat/fs-watcher-live-refresh
Jul 12, 2026
Merged

feat(watch): live-refresh on external .git changes + fetch-on-focus#7
jcardonne merged 1 commit into
mainfrom
feat/fs-watcher-live-refresh

Conversation

@jcardonne

Copy link
Copy Markdown
Owner

What

Makes GitChef react to changes automatically, closing the gap the user hit: deleted-upstream branches lingering until a manual Fetch.

1. Filesystem watcher (src-tauri/src/watch.rs) - instant local reactivity

  • Watches the repo's git dir(s) (worktree gitdir + shared commondir) via notify-debouncer-mini, 400ms debounce collapsing an op's write burst into one repo-changed event.
  • Frontend does a local refresh({stats:false}) on the event - zero network, nothing to rate-limit.
  • Reacts to commit/checkout/stash/rebase done from a terminal or another tool.
  • Watcher handles kept in Tauri state; started on repo load, dropped on tab close; idempotent per path.

2. Fetch-on-focus - the missing half of remote reactivity

  • Regaining window focus now also network-fetches (prune included) when auto-fetch is enabled, throttled to the configured interval via a single self-gating backgroundFetch() shared with the interval timer.

Already existed (not rebuilt)

Periodic auto-fetch (Off/1/5/15min, Settings, default Off), auto-prune on pull + fetch --all --prune, focus/visibility local refresh.

Review + hardening

Code-review agent + ponytail pass run on the diff. Fixes applied:

  • Watcher leak if a tab closed during the initial load await - re-check liveness before watchRepo.
  • Throttle only honoured one way - moved the throttle into backgroundFetch so interval + focus share one clock (no double-fetch).
  • Debounced echo of our own writes - listener skips within a grace window after an op settles (lastOpAt), not just while busyRef is set.
  • Ponytail: de-duplicated the two background-fetch call sites into one helper.

Verify

  • New watcher integration test (real notify chain fires on a .git write + idempotency): pass
  • Full Rust suite green, 56 frontend tests green, tsc clean, build clean

Note

Auto-fetch still defaults to Off. The watcher (local reactivity) is always on; remote pruning stays manual/auto-fetch-gated unless we flip that default - open question for a follow-up.

https://claude.ai/code/session_01RVF5LSdTyciWKY1k5sedU8

Add a filesystem watcher so the graph/branches update the instant git state
changes underneath the app - a commit/checkout/stash/rebase from a terminal or
another tool - without a manual refresh. Watches the repo's git dir(s) (worktree
gitdir + shared commondir) via notify-debouncer-mini, collapsing each op's write
burst into one debounced `repo-changed` event; handles live in Tauri state,
started on repo load and dropped on tab close. Purely local: no network, so
nothing to rate-limit.

Also make regaining window focus pull remote state (prune included) when
auto-fetch is enabled, throttled to the configured interval via a single
self-gating backgroundFetch() shared with the interval timer.

Hardening: the watcher listener skips our own writes' debounced echo (in-flight
via busyRef, just-settled via lastOpAt) so a fast local op can't refresh twice,
and the load path re-checks liveness after its initial refresh so closing a tab
mid-load cannot leak a watcher.
@jcardonne
jcardonne merged commit 4a63c20 into main Jul 12, 2026
2 checks passed
@jcardonne
jcardonne deleted the feat/fs-watcher-live-refresh branch July 12, 2026 21:28
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 0.29.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant