Skip to content

fix(git): fix canonical_root for worktrees and subdirectory projects#672

Open
anivaryam wants to merge 4 commits into
DeusData:mainfrom
anivaryam:main
Open

fix(git): fix canonical_root for worktrees and subdirectory projects#672
anivaryam wants to merge 4 commits into
DeusData:mainfrom
anivaryam:main

Conversation

@anivaryam

Copy link
Copy Markdown

Summary

Fixes #659detect_changes returns empty impacted_symbols for projects indexed inside git worktrees or as repo subdirectories because canonical_root was computed incorrectly.

Root cause: git rev-parse --git-common-dir outputs a path relative to the directory passed via -C (the indexed path, input_path), not to worktree_root. Two errors in derive_canonical_root():

  1. The relative git_common_dir (e.g. "../.git") was joined with worktree_root instead of input_path. For a project at workspace/scripts/, worktree_root is workspace/ but the relative path is relative to scripts/ — joining it with workspace/ produced workspace/../.git, which strips to workspace/...
  2. Even if joined correctly (scripts/../.git), stripping the /.git suffix leaves scripts/.. — a path with unresolved .. components. Without normalization this is stored as-is and never matches the project's stored root path.

Fix (src/git/git_context.c):

  • Pass input_path (the original indexed directory) as the join base for relative git_common_dir paths.
  • Call realpath() (POSIX) / _fullpath() (Windows) on the joined .git path before stripping the suffix. The .git directory always exists for a valid repository, so the call succeeds and collapses any .. components.

Tests (tests/test_git_context.c):
Three new tests in suite_git_context:

Test plan

  • canonical_root_repo_root passes
  • canonical_root_subdir passes (was failing before fix)
  • canonical_root_linked_worktree passes (was failing before fix)
  • Full make test suite has no regressions

git rev-parse --git-common-dir outputs a path relative to the directory
passed via -C (the indexed path), not to worktree_root. When the indexed
path is a subdirectory of the repo root, or a linked worktree sibling,
joining the relative git_common_dir with worktree_root produced a path
with unresolved ".." components. Stripping the "/.git" suffix then left
e.g. "/workspace/.." rather than "/workspace".

Two changes in derive_canonical_root():
1. Use input_path (the original indexed directory) as the join base for
   relative git_common_dir paths, so "../.git" from scripts/ resolves
   against scripts/, not against the already-resolved worktree root.
2. Call realpath() (POSIX) / _fullpath() (Windows) on the joined .git
   path before stripping the suffix, collapsing any ".." components into
   the canonical filesystem path. The .git directory always exists for a
   valid repository, so realpath() succeeds.

Add test_git_context.c covering all three cases:
- repo indexed from its root (existing behaviour, must not regress)
- project inside a repo, indexed from a subdirectory (issue DeusData#659)
- project in a linked git worktree (issue DeusData#659 primary case)

Fixes DeusData#659

Signed-off-by: anivaryam <anivaryam.dev@gmail.com>
check-no-test-skips.sh prohibits plain SKIP(); git worktree add is
available since git 2.5 (2015) so failure is a real error, not a
platform/version skip.

Signed-off-by: anivaryam <anivaryam.dev@gmail.com>
- Replace MAX_PATH (requires windows.h) with 4096 in both
  src/git/git_context.c and tests/test_git_context.c; use
  sizeof(resolved) instead of the literal for _fullpath()
- Wrap canonical_root_linked_worktree body in #ifdef _WIN32 / #else /
  #endif so realpath() is excluded from Windows compilation
  (SKIP_PLATFORM is a runtime skip — the body still compiled)

Signed-off-by: anivaryam <anivaryam.dev@gmail.com>
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.

detect_changes: impacted_symbols always empty for projects inside git worktrees (canonical_root miscalculated)

1 participant