Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/services/__tests__/file-watcher.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,17 @@ describe('FileWatcher debounce / cooldown / suppress state machine', () => {
expect(onChange).not.toHaveBeenCalled();
});

it('watches the worktree registry, not each worktree\'s private state', () => {
// `worktrees/**` also matched every worktree's runtime files (index.lock,
// FETCH_HEAD, COMMIT_EDITMSG, logs/**). In a linked worktree that set is
// our OWN gitdir, so the panel's git commands fed its own watcher — an
// endless refresh that restarted any in-flight history search. Only the
// registry entries `worktree list` actually reports are worth watching.
const patterns = h.watchers.map(w => w.pattern.pattern);
expect(patterns).toContain('worktrees/*/{HEAD,gitdir,locked}');
expect(patterns).not.toContain('worktrees/**');
});

it('does not fire when disabled', () => {
fw.enabled = false;
fireOn('**', `${REPO}/src/a.ts`);
Expand Down
10 changes: 9 additions & 1 deletion src/services/file-watcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,15 @@ export class FileWatcher implements vscode.Disposable {
this.addWatcher(new vscode.RelativePattern(this.commonDir, 'refs/stash'));
this.addWatcher(new vscode.RelativePattern(this.commonDir, 'packed-refs'));
this.addWatcher(new vscode.RelativePattern(this.commonDir, 'config'));
this.addWatcher(new vscode.RelativePattern(this.commonDir, 'worktrees/**'));
// Only the registry entries `git worktree list` reports: the admin dir
// appearing/disappearing (gitdir), where each worktree points (HEAD), and
// its lock state. NOT `worktrees/**` — that also matched every worktree's
// private runtime state (index, index.lock, FETCH_HEAD, COMMIT_EDITMSG,
// logs/**). For a linked worktree that state IS our own gitdir, so the
// panel's own `git status` retriggered its own watcher: a refresh loop
// that also restarted any in-flight history search. For a main repo it
// meant every git command in a sibling worktree forced a full refresh.
this.addWatcher(new vscode.RelativePattern(this.commonDir, 'worktrees/*/{HEAD,gitdir,locked}'));

// Watch working tree for file changes (exclude heavy dirs via specific patterns)
// Using {src,lib,app,...}/** would be too restrictive, so we watch ** but filter
Expand Down