Skip to content

Linked git worktrees: git_changed watcher never fires + freshness ignores uncommitted changes #16

Description

@brendanwhit

Two related worktree/uncommitted-diff bugs found while reviewing an uncommitted diff in a linked git worktree (v0.7.0).

1. watchRepo never fires git_changed in linked worktrees

server/session.ts (~L476):

const gitDir = join(this.repoPath, '.git');
...
const indexPath = join(gitDir, 'index');
const headPath = join(gitDir, 'HEAD');

In a linked worktree (git worktree add), repoPath/.git is a file containing gitdir: /main/repo/.git/worktrees/<name>, not a directory. statSync(indexPath) / readFileSync(headPath) throw on every poll tick, the catch blocks swallow it, and git_changed never broadcasts — so open browser tabs never learn the working tree changed and keep rendering the stale diff (the server's getItemData('diff') is live, so a manual reload shows current state; the UI just never asks).

Fix: resolve the real git dir, e.g. git rev-parse --git-dir (or read the gitdir: pointer when .git is a file). Note the worktree's HEAD and its index both live in the per-worktree gitdir (.git/worktrees/<name>/).

2. Freshness diffs base...HEAD, but the UI diff includes the working tree

getBranchDiff (used by the diff item) deliberately includes uncommitted/staged changes ("so the review UI reflects the live state of the checkout"). But getBranchDiffRaw (used to compute analysis freshness) runs:

gitRun(repoPath, 'diff', '--raw', '--no-abbrev', `${baseBranch}...HEAD`);

With an entirely-uncommitted diff (no commits on the branch), that's empty — so read_analysis freshness reports every analyzed file in removedFiles, and a refresh flow trusting it would delete the whole analysis. The two functions should agree on what "the diff" is; getBranchDiffRaw could diff mergeBase → working tree over the same file set getBranchDiff computes.

Repro

  1. git worktree add a branch, make working-tree-only changes (no commits).
  2. claim_reviews + set_analysis, open the UI.
  3. Edit files — UI never refreshes (bug 1).
  4. read_analysis → freshness lists all analyzed files as removedFiles (bug 2).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions