What happened?
When typing @ in the prompt to insert a file reference, the autocomplete suggestion list shows submodule directories but lists no files inside them. Only files from the root (parent) repository are reachable via @ completion.
Steps to reproduce:
- Open a project that contains one or more Git submodules.
- Start typing
@ in the prompt to trigger file completion.
- Navigate into the submodule folder: it appears in the list, but expanding it shows nothing.
What did you expect to happen?
Files tracked inside the submodule should be listed under their submodule directory, exactly as they appear on disk and in git ls-files --recurse-submodules. For example, if the project has a submodule at third-party/lib with a file src/helpers.ts, then @third-party/lib/src/helpers.ts should be selectable.
Client information
Client Information
- Version: 0.16.1
- Affected file:
packages/core/src/utils/filesearch/crawler.ts
- Platform: Linux / macOS / Windows (any OS where Git submodules are used)
Login information
Introduced in commit 664208c ("feat(core): replace fdir crawler with git ls-files + ripgrep fallback").
The file crawler in packages/core/src/utils/filesearch/crawler.ts uses git ls-files --cached to enumerate tracked files. Without the --recurse-submodules flag, Git returns each submodule as a single opaque entry (the submodule commit SHA recorded in the parent index) rather than recursing into it and listing its individual files.
- const trackedArgs = ['--literal-pathspecs', 'ls-files', '--cached'];
+ const trackedArgs = ['--literal-pathspecs', 'ls-files', '--cached', '--recurse-submodules'];
The previous crawling strategy (fdir / ripgrep) was purely filesystem-based and naturally descended into submodule directories, so this is a regression.
The inconsistency is also visible in the fallback paths: if git ls-files fails for any reason, the ripgrep/fdir fallback kicks in and does return submodule files: meaning the same project can see different results depending on which code path runs.
Fix
Add --recurse-submodules to the git ls-files --cached invocation. Git explicitly supports the -t output-format flag alongside --recurse-submodules (--others/--deleted modes are the unsupported ones). If the flag is unavailable on a very old Git version, the command will fail and the ripgrep/fdir fallback will handle it transparently.
A regression test that creates a real parent repo with a real submodule and verifies crawler output has been added in packages/core/src/utils/filesearch/crawler.test.ts.
Anything else we need to know?
The status === 'S' guard in processTrackedFile (line 1071) was not related to submodules: S in git ls-files -t output is the skip-worktree flag used by sparse checkouts, not a submodule marker. Submodule commit entries appear with status H without --recurse-submodules and are replaced by the actual contained files when --recurse-submodules is active.
What happened?
When typing
@in the prompt to insert a file reference, the autocomplete suggestion list shows submodule directories but lists no files inside them. Only files from the root (parent) repository are reachable via@completion.Steps to reproduce:
@in the prompt to trigger file completion.What did you expect to happen?
Files tracked inside the submodule should be listed under their submodule directory, exactly as they appear on disk and in
git ls-files --recurse-submodules. For example, if the project has a submodule atthird-party/libwith a filesrc/helpers.ts, then@third-party/lib/src/helpers.tsshould be selectable.Client information
Client Information
packages/core/src/utils/filesearch/crawler.tsLogin information
Introduced in commit
664208c("feat(core): replace fdir crawler with git ls-files + ripgrep fallback").The file crawler in
packages/core/src/utils/filesearch/crawler.tsusesgit ls-files --cachedto enumerate tracked files. Without the--recurse-submodulesflag, Git returns each submodule as a single opaque entry (the submodule commit SHA recorded in the parent index) rather than recursing into it and listing its individual files.The previous crawling strategy (fdir / ripgrep) was purely filesystem-based and naturally descended into submodule directories, so this is a regression.
The inconsistency is also visible in the fallback paths: if
git ls-filesfails for any reason, the ripgrep/fdir fallback kicks in and does return submodule files: meaning the same project can see different results depending on which code path runs.Fix
Add
--recurse-submodulesto thegit ls-files --cachedinvocation. Git explicitly supports the-toutput-format flag alongside--recurse-submodules(--others/--deletedmodes are the unsupported ones). If the flag is unavailable on a very old Git version, the command will fail and the ripgrep/fdir fallback will handle it transparently.A regression test that creates a real parent repo with a real submodule and verifies crawler output has been added in
packages/core/src/utils/filesearch/crawler.test.ts.Anything else we need to know?
The
status === 'S'guard inprocessTrackedFile(line 1071) was not related to submodules:Singit ls-files -toutput is the skip-worktree flag used by sparse checkouts, not a submodule marker. Submodule commit entries appear with statusHwithout--recurse-submodulesand are replaced by the actual contained files when--recurse-submodulesis active.