fix(projects): resolve git worktree .git files in detect_project - #12
Open
GetsEclectic wants to merge 1 commit into
Open
fix(projects): resolve git worktree .git files in detect_project#12GetsEclectic wants to merge 1 commit into
GetsEclectic wants to merge 1 commit into
Conversation
Any `trc` write from inside a git worktree silently truncated the parent checkout's .trace/issues.jsonl. In a worktree, `.git` is a *file* (`gitdir: <path>`), not a directory; detect_project() accepted that file as a repo root, so _extract_*_from_git_remote() found no config, the fallbacks registered the worktree as a brand-new project, and the next export_to_jsonl clobbered the real file with the (empty) worktree-project's issue set. Add _resolve_git_dir() which resolves a worktree pointer the way git does (follow gitdir: -> read commondir -> canonical .git -> main checkout root), so a worktree resolves to the same id/name/path as the main checkout. Adds tests/test_worktree_detect_project.py (no git binary needed for the unit-level resolver test; a real `git worktree add` for the integration test).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem (data loss)
Any
trc create/close/updaterun from inside a git worktreesilently truncates the parent checkout's
.trace/issues.jsonlto a per-worktree(usually empty) subset — dropping every issue the main checkout had.
Reproduction:
This bites hard with parallel agents, each working in its own worktree.
Root cause
In a worktree,
.gitis a file containinggitdir: <path>, not adirectory.
detect_project()walked up to that.gitandPath.exists()returned
True, so it treated the worktree dir as a repo root:project_pathbecame the worktree dir._extract_*_from_git_remote(git_dir)openedgit_dir / "config", whichdoesn't exist (git_dir is a file), so both returned
Noneand the fallbacksassigned the worktree path/name as a brand-new project identity.
Every worktree thus registered as a new project, and the next write called
export_to_jsonl, which doespath.open("w")and writes only the(new, empty) worktree-project's issues — clobbering the real file.
Fix
Add
_resolve_git_dir()which resolves a.gitpointer file the way gititself does — follow
gitdir:→ readcommondir→ locate the canonical.git→ return the main checkout root.detect_project()now uses it, so aworktree resolves to the same id / name / path as the main checkout.
configis then read from the canonical.git, restoring correct remote-basedidentity. Concurrent worktrees agree on one project identity, matching the
JSONL-line-merge model the project already relies on.
Tests
tests/test_worktree_detect_project.py:_resolve_git_dirresolves a hand-built worktree pointer to canonical.git+ main root (no git binary needed).detect_project()from inside a realgit worktree addreturns identityidentical to the main checkout (same id, name, and path).
Follow-up (separate PR)
Even with identity fixed,
.trace/issues.jsonlstill physically lives underwhatever
.trace/is in the current worktree. Teachingsync_project/export_to_jsonlto always write to the project root's.trace/wouldfully de-race concurrent worktrees. Gated on this PR.