.cbmignore patterns silently ignored on Windows
Environment
- codebase-memory-mcp: v0.6.0 (latest)
- OS: Windows 11, amd64
- Installed via
install.ps1
Description
.cbmignore patterns are not applied during indexing on Windows. The file is read without error but exclusions have no effect — the node count is identical with and without the file present.
This is distinct from but related to #234. That issue reports .gitignore not being respected on Linux, with .cbmignore as the working workaround. On Windows, the .cbmignore workaround itself does not work, leaving no mechanism for excluding directories from the index.
Steps to reproduce
- Create
.cbmignore at the repo root with a simple directory pattern:
- Delete the existing project index:
index_repository → delete_project → index_repository
- Confirm the excluded directory is still fully indexed:
search_graph(project="...", name_pattern=".*SomeFunctionFromExcludedDir.*")
Expected behaviour
Zero results — the excluded directory should not appear in the index.
Actual behaviour
The excluded directory is fully indexed. Node and edge counts are identical before and after adding .cbmignore. Incremental re-index and full delete+re-index both produce the same result.
Suspected root cause
The .cbmignore file is loaded correctly (the file path is constructed and opened), but pattern matching against directory paths likely fails due to Windows path separator mismatch.
In discover.c, the cbmignore path is constructed as:
snprintf(gi_path, sizeof(gi_path), "%s/.cbmignore", repo_path);
On Windows, repo_path arrives as a native Windows path (e.g. C:\Users\user\project), producing a mixed-separator path C:\Users\user\project/.cbmignore. The file opens successfully, but during directory walking, rel_path values may be computed with \ separators while the patterns in .cbmignore use /. Since glob_match in gitignore.c does no separator normalization, glob_match("graphiti", "graphiti") would work but glob_match("foo/graphiti", "foo\graphiti") would not.
Tested patterns that all failed (delete + full re-index between each attempt):
graphiti/
odin-ai-graphiti-mcp/graphiti/
odin-ai-graphiti-mcp/graphiti
graphiti
odin-ai-graphiti-mcp\graphiti
The backslash-separator variant was tested specifically to probe whether rel_path uses \ internally on Windows. It also failed, which eliminates the path separator mismatch as the sole cause and suggests the .cbmignore file may not be loaded or applied at all on Windows — the patterns appear to be silently discarded before matching rather than matching incorrectly.
Suggested fix
Add a Windows-specific code path that normalises rel_path separators to / before passing to cbm_gitignore_matches, and verify that the .cbmignore file is successfully opened on Windows when repo_path uses native \ separators. A debug log line confirming the cbmignore path and pattern count at startup would help narrow down whether the issue is in file loading or pattern matching.
Workaround
None currently available on Windows.
The documentation suggests symlinks are skipped during traversal, which could in theory be used to exclude a directory. In practice this is not viable here: the excluded directory is a git submodule, so replacing it with a symlink breaks git submodule tracking and Docker volume mounts (which do not reliably follow symlinks on Windows).
Query-time file_pattern filtering can partially mitigate the impact but does not reduce index size or improve visualization.
.cbmignorepatterns silently ignored on WindowsEnvironment
install.ps1Description
.cbmignorepatterns are not applied during indexing on Windows. The file is read without error but exclusions have no effect — the node count is identical with and without the file present.This is distinct from but related to #234. That issue reports
.gitignorenot being respected on Linux, with.cbmignoreas the working workaround. On Windows, the.cbmignoreworkaround itself does not work, leaving no mechanism for excluding directories from the index.Steps to reproduce
.cbmignoreat the repo root with a simple directory pattern:Expected behaviour
Zero results — the excluded directory should not appear in the index.
Actual behaviour
The excluded directory is fully indexed. Node and edge counts are identical before and after adding
.cbmignore. Incremental re-index and full delete+re-index both produce the same result.Suspected root cause
The
.cbmignorefile is loaded correctly (the file path is constructed and opened), but pattern matching against directory paths likely fails due to Windows path separator mismatch.In
discover.c, the cbmignore path is constructed as:On Windows,
repo_patharrives as a native Windows path (e.g.C:\Users\user\project), producing a mixed-separator pathC:\Users\user\project/.cbmignore. The file opens successfully, but during directory walking,rel_pathvalues may be computed with\separators while the patterns in.cbmignoreuse/. Sinceglob_matchingitignore.cdoes no separator normalization,glob_match("graphiti", "graphiti")would work butglob_match("foo/graphiti", "foo\graphiti")would not.Tested patterns that all failed (delete + full re-index between each attempt):
The backslash-separator variant was tested specifically to probe whether
rel_pathuses\internally on Windows. It also failed, which eliminates the path separator mismatch as the sole cause and suggests the.cbmignorefile may not be loaded or applied at all on Windows — the patterns appear to be silently discarded before matching rather than matching incorrectly.Suggested fix
Add a Windows-specific code path that normalises
rel_pathseparators to/before passing tocbm_gitignore_matches, and verify that the.cbmignorefile is successfully opened on Windows whenrepo_pathuses native\separators. A debug log line confirming the cbmignore path and pattern count at startup would help narrow down whether the issue is in file loading or pattern matching.Workaround
None currently available on Windows.
The documentation suggests symlinks are skipped during traversal, which could in theory be used to exclude a directory. In practice this is not viable here: the excluded directory is a git submodule, so replacing it with a symlink breaks git submodule tracking and Docker volume mounts (which do not reliably follow symlinks on Windows).
Query-time
file_patternfiltering can partially mitigate the impact but does not reduce index size or improve visualization.