fix(extraction): index nested repos recorded as gitlinks (#1031, #1033)#1038
Merged
Conversation
A nested git repo tracked as a gitlink (mode 160000) — a clone `git add`ed into the super-repo without a `.gitmodules` entry, or a submodule that isn't active/initialized in this checkout — fell through both file-collection passes: it's tracked, so the untracked `-o` listing skips it, but it's not an active submodule, so `--recurse-submodules` won't expand it. Indexing the top level therefore pulled in only the outer repo's own files and stopped at the nested repo's boundary (one report: ~10 files at the root). Switch the tracked scan to `ls-files -s` to expose file modes, collect the unexpanded 160000 entries, and recurse into each that has a real working tree on disk as its own embedded repo. Mirror the same discovery in discoverEmbeddedRepoRoots so the watcher's scope stays equal to the indexer's. Active submodules (#147) and untracked nested clones (#193) are unchanged; gitlinks under default-ignored dirs (vendor/, node_modules/) stay excluded (#407); an uninitialized submodule with no checkout on disk is left alone. Adds four-shape coverage in extraction.test.ts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 28, 2026
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
Running
codegraph initat the root of a workspace built by stacking repos inside one another indexed only the outer repo's own files and stopped at the nested repo's boundary — a stacked-repo project came up nearly empty (#1031 saw ~10 files at the root; #1033 reported the same for submodule/gitlink modules).Root cause
In
collectGitFiles, a nested repo tracked as a gitlink (mode160000) fell between the two file-collection passes:git ls-files -opass never reports it, andgit added without a.gitmodulesentry, or a submodule that isn't initialized in this checkout), so--recurse-submoduleswon't expand it.So its source was silently skipped.
Fix
ls-files -c→ls-files -s --recurse-submodulesto expose each entry's mode. Because active submodules are expanded inline by--recurse-submodules, any160000entry is by definition an unexpanded gitlink — a precise signal, no heuristics..gitcheckout on disk (classifyGitDir(...) === 'embedded') and isn't under a default-ignored dir, indexing it as its own embedded repo.discoverEmbeddedRepoRootsso the file-watcher's scope stays equal to the indexer's (the "must not diverge" invariant).Unchanged: active submodules (#147), plain untracked nested clones (#193). Excluded as before: gitlinks under
vendor/,node_modules/, etc. (#407). A submodule with nothing checked out on disk is correctly left alone.Tests — four-shape coverage (
extraction.test.ts)bare gitlink (recursively) · gitlink alongside an active submodule · gitlink under a default-ignored dir (excluded) · uninitialized submodule (left alone).
Validation
codegraph initon real A/B/C/D fixtures (scenario B: 1 → 3 files).npm ci+ build + the gitlink/submodule/nested tests (10 passed) + live binary four-shape check.npm ci+ build + the same tests (10 passed).Closes #1031.
Partially addresses #1033 — this fixes the gitlink/submodule indexing facet. The two Windows-specific facets remain open: junction/symlink-dir traversal in the non-git filesystem walk, and the shared-
.codegraph-via-junction index degradation.🤖 Generated with Claude Code