Replace the manual join(input_path, --git-common-dir) + realpath/_fullpath with
`git rev-parse --path-format=absolute --git-common-dir` (git 2.31+), which returns
git's own absolute, canonical common-dir. Because a main repo and its linked
worktree both query the same git binary, they resolve to the IDENTICAL path, so
canonical_root is consistent across worktrees and platforms with no
platform-specific path canonicalization.
This is the truly platform-agnostic #659 fix:
- git resolves the relative ".." internally, so a project indexed from a
subdirectory gets the real repo root (the #659 bug).
- No realpath/_fullpath, so the msys-vs-native path-representation divergence that
broke the worktree==main-root invariant (test_pipeline.c
git_context_linked_worktree) on the Windows CI leg is eliminated — both sides
get git's single canonical representation.
Falls back to the previous relative-join derivation (Unix realpath) when git is
older than 2.31 and doesn't support --path-format (abs_common_dir empty). The
input_path-join fix and the Windows test-harness SKIP_PLATFORM guards from the
earlier commits on this branch remain for that fallback path.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Co-Authored-By: anivaryam <anivaryam.dev@gmail.com>
detect_changes returned an empty impacted_symbols set for projects indexed
inside a git worktree or from a repo subdirectory (#659): canonical_root was
computed wrong. `git rev-parse --git-common-dir` emits a path relative to the
directory passed via -C (input_path), NOT to worktree_root, and the "/.git"
suffix was stripped textually without resolving ".." components. So e.g.
"../.git" joined against worktree_root, or "/ws/scripts/../.git" strip, left an
unresolved ".." and never matched the project's stored root path.
Fix (src/git/git_context.c): join the relative --git-common-dir against
input_path (the -C dir) instead of worktree_root, and realpath()/_fullpath()-
normalize the result BEFORE stripping "/.git" (the .git dir always exists for a
valid repo, so resolution succeeds). This is consistent with the existing
realpath'd root_path used for prefix matching (mcp.c).
Reproduce-first: tests/test_git_context.c. The subdirectory case is the genuine
guard — a repo indexed from a subdir yields a *relative* --git-common-dir, so the
unfixed code leaves an un-normalized "<root>/subdir/.." (verified RED; GREEN after
the realpath fix). The linked-worktree case is a supporting invariant, not the
#659 reproducer: git that emits an *absolute* worktree --git-common-dir (e.g.
2.48.x) doesn't manifest the bug, so it passes either way; it still enforces the
worktree->main-root invariant. All three git-based tests SKIP_PLATFORM on Windows
(the CI shell there cannot init a repo via system()).
Distilled from #672 (thanks @anivaryam); that PR's production fix is taken
verbatim. Its repo_root/subdir tests ran git unconditionally and failed the
Windows CI leg ("failed to init git repo"); here all three git-based tests are
Windows-skipped so ci-ok is green cross-platform. Supersedes #696, which only
realpath'd after the strip without changing the join base and so still yielded
the workspace parent for the subdirectory case.
Closes#659
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Co-Authored-By: anivaryam <anivaryam.dev@gmail.com>