Skip to content

fix: collapse worktrees to main repo, ignore $HOME-as-git-root#212

Open
NovakPAai wants to merge 1 commit into
mainfrom
fix/git-root-worktree-and-home
Open

fix: collapse worktrees to main repo, ignore $HOME-as-git-root#212
NovakPAai wants to merge 1 commit into
mainfrom
fix/git-root-worktree-and-home

Conversation

@NovakPAai
Copy link
Copy Markdown
Collaborator

Summary

Sessions whose cwd lives inside a linked git worktree, or sessions launched from \$HOME when home itself happens to be a git repo, were being mismapped to the wrong project / wrong GitHub remote in the dashboard.

This PR fixes resolveGitRoot() in src/data.js so the project identity (and downstream remote inference) is stable for those cases.

Changes

  • Linked worktrees collapse to the main repo. git worktree list --porcelain is parsed for its first record (the main worktree) before falling back to rev-parse --show-toplevel. Previously every linked worktree appeared as its own "project".
  • Bare repos are skipped. Paths ending in .git (what --porcelain reports for bare repos) are dropped — downstream code assumes a working tree.
  • Symlinked paths are normalized via fs.realpathSync so macOS /var vs /private/var doesn't duplicate the same physical project.
  • \$HOME-as-git-root is rejected. When the home directory itself is a git repo (e.g. a dotfiles repo), sessions launched from home no longer inherit that remote.
  • Disk cache filename bumped to -v2.json to invalidate stale entries from before the fix.

Tests

test/git-root-resolve.test.js — 7 cases:

  • 3 unit tests for _parseMainWorktree (happy path, empty input, lines that look like records but aren't).
  • 4 integration tests using real git in os.tmpdir(): linked worktree → main, bare repo → empty, symlink → normalized to real path, \$HOME-as-git-root → empty (skipped if home isn't a repo on the machine).

All 7 pass locally. Pre-existing test/wsl-windows.test.js failure on macOS is unrelated to this change.

Deferred (out of scope)

  • Atomic disk-cache writes (writeFileSync → tmp + rename). Project-wide pattern in the existing cache helpers; addressing it here would balloon the diff.
  • Debug-log on the silent porcelain → rev-parse fallback. Zero-dependency project has no logger; left as a comment-level TODO.

Test plan

  • Run node --test test/git-root-resolve.test.js — all 7 pass.
  • In the dashboard, sessions whose cwd was a linked worktree now group under the main repo's project card.
  • Sessions whose cwd is \$HOME (when home is a git repo) no longer carry that repo's remote.

resolveGitRoot now:
- Uses `git worktree list --porcelain` first record to map linked
  worktrees to the main repo (was: separate "project" per worktree).
- Drops bare-repo paths (root ending in .git) so they don't pollute
  downstream code expecting a working tree.
- Normalizes the result via realpath so /var <-> /private/var on macOS
  doesn't duplicate the same physical project.
- Rejects roots that equal $HOME, fixing the bug where sessions
  launched from home inherited the dotfiles repo's remote and
  mismapped to the wrong GitHub project.

Disk cache bumped to -v2.json to invalidate stale entries.

Tests: 7 cases in test/git-root-resolve.test.js - unit tests for
the porcelain parser + integration tests using real `git init` /
`git worktree add` / bare init / symlink in tmpdir.

Deferred (tracked separately): atomic disk-cache writes (project-wide
pattern), debug-log on porcelain fallback.
@NovakPAai
Copy link
Copy Markdown
Collaborator Author

Merge sequence

Merge this PR first. It has no conflicts with main and is needed as the foundation for #213.

After this merges:

#213 is not safe to merge before this one — without the bare-repo skip + $HOME rejection + symlink normalization from this PR, the getKnownGitRoots() set used by /api/repo-refresh/trigger and initOnStartup would contain spurious entries.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants