ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

codebase-memory-mcp `.cbmignore` 完全指南:用 gitignore 语法精确控制代码索引范围

codebase-memory-mcp `.cbmignore` 完全指南:用 gitignore 语法精确控制代码索引范围 codebase-memory-mcp.cbmignore完全指南用 gitignore 语法精确控制代码索引范围【免费下载链接】codebase-memory-mcpHigh-performance code intelligence MCP server. Indexes codebases into a persistent knowledge graph — average repo in milliseconds. 158 languages, sub-ms queries, 99% fewer tokens. Single static binary, zero dependencies.项目地址: https://gitcode.com/GitHub_Trending/co/codebase-memory-mcp.cbmignore是 codebase-memory-mcp 的项目级索引排除文件它决定索引器在“文件发现discovery”阶段能看见哪些文件进而决定哪些代码进入知识图谱、哪些被挡在图谱之外。本文以官方文档 docs/cbmignore.md 为核心骨架结合 src/discover/gitignore.c 与 src/discover/discover.c 的底层实现完整讲解其语法、生效阶段、五层优先级、否定语义与验证手段帮助你为真实仓库配置出干净、精准、可预期的索引范围。一、.cbmignore是什么、在哪里生效.cbmignore是一个项目专属的忽略文件用于控制索引器在遍历目录directory walk挑选文件时能看到哪些文件。它有四个关键特性gitignore 风格语法通配符书写习惯与.gitignore基本一致上手成本低只能放在被索引目录的根只从根目录读取repo/.cbmignore嵌套在子目录里的.cbmignore不会被读取在“文件发现时间点”生效它作用于目录遍历阶段。初始index_repository、手动重新索引、后台自动同步等所有索引路径走的是同一套发现逻辑因此被.cbmignore匹配的路径永远不进入知识图谱而不是进入后再被剔除对 git 本身没有任何影响它只塑造索引器所见git的提交、历史、分支不受影响。可以把它提交到仓库与团队共享索引排除规则也可以把它写进.gitignore让个人化的排除规则不被纳入版本管理。README 的 Ignoring Files 一节也把完整过滤描述为分层结构内置硬编码模式.git、node_modules等→.gitignore层级 →.cbmignore见 README.md。从源码结构看.cbmignore还被增量语义清单semantic manifest视为仓库根的“控制文件”control file之一见 src/pipeline/pipeline_incremental.c说明它是与项目深度集成的配置载体而非临时开关。生效时机提醒.cbmignore的改动在下一次重新索引时才生效修改后请触发一次 re-index。二、语法速查表与逐条解读.cbmignore的规则是每行一个 pattern空行被忽略以#开头的行是注释行尾空白会被裁剪。语法特性含义*匹配任意一串字符但不能匹配/?匹配恰好一个字符不能匹配/**可跨越目录边界如**/name、dir/**、a/**/b[abc]、[a-z]字符类[!a-z]/[^a-z]对字符类取反结尾/pattern 只匹配目录不匹配同名文件其他位置的/将 pattern锚定到仓库根rooted/anchoredpattern 中不含/按文件/目录名称在任意深度匹配开头!否定——重新包含先前被排除的路径最后一个匹配的 pattern 生效官方示例全收录# 树中任意位置生成的 protobuf 输出 *.pb.go # 一个特定的顶层目录前导 / 锚定到仓库根 /third_party/ # 任意深度下名为 snapshots 的目录结尾 / 仅目录 snapshots/ # 任意 fixtures 目录下的所有内容 **/fixtures/** # 锚定的 glob任意单字符 API 版本下的生成客户端 /api/v?/generated/ # 字符类2020-2029 的年度日志目录 /logs/202[0-9]/ # 忽略所有 YAML但保留 CI 配置否定——最后一个匹配生效 *.yaml !ci.yaml源码层的模式匹配引擎这张语法表在 src/discover/gitignore.c 中由一套完整的 gitignore 风格引擎支撑。每条规则解析后被归一化为结构体见 src/discover/gitignore.ctypedef struct { char *pattern; /* the glob pattern (normalized) */ bool negated; /* starts with ! */ bool dir_only; /* ends with / */ bool rooted; /* contains / (anchored to root) */ } gi_pattern_t;解析阶段gi_add_pattern依次剥离首字符!否定、结尾/仅目录、前导/锚定根再扫描剩余文本是否仍含/——只要含/即视为 rooted。匹配阶段*、**、?、字符类各有独立递归函数入口为 glob_match**分支见 glob_match_doublestar字符类支持[!...]/[^...]取反与a-z区间见 glob_match_charclass。未锚定 pattern 的匹配策略match_unrooted先用basename匹配一次不中则从相对路径的每一个/边界处逐一尝试完整匹配——这正是“无/的 pattern 命中任意深度同名条目”的实现方式。“最后匹配生效”遍历所有 pattern 时命中即记录p-negated ? -1 : 1见 cbm_gitignore_match_result循环结束时最后一次命中值即为最终结论。一个值得注意的健壮性设计**的组合回溯在最坏情况下是指数级的而所有被发现的路径都要与每个 pattern 比对因此引擎对每个 (pattern, path) 对设置了步数预算GI_MATCH_MAX_STEPS 20000见 src/discover/gitignore.c。预算耗尽时报告“不匹配”——病态 pattern 的后果是文件被照常索引可恢复方向而不是误删用户文件普通 glob 通常几十步即可完成匹配实际不受影响。三、发现阶段的完整优先级文档明确发现过程按固定顺序应用各层过滤器总体规则是“先拒绝路径的层级获胜”但.cbmignore的否定第 4 层可以解除第 1 层的内置跳过目录安全核心除外也能把路径从第 5 层 git 全局排除中“救”回来。对目录而言完整处理顺序如下内置跳过列表——.git、node_modules、dist、target、vendor、工具缓存等60 个名称fast/moderate 索引模式追加更多目录如docs、examples、testdata。.cbmignore否定例如!target/可解除普通内置跳过目录但安全核心除外.git、node_modules、.worktrees、.claude-worktrees这四个永远不可被解除。仓库.gitignore——repo/.gitignore与git-common-dir/info/exclude合并worktree 感知冲突时靠后的 pattern 生效即使被索引目录不是 git 仓库根也会被遵守。嵌套.gitignore——遍历过程中就近拾取规则相对其所在目录解析源码见 local_rel_path 与 try_load_nested_gitignore。.cbmignore——正向匹配跳过否定匹配可解除第 1 层普通内置跳过目录、救回第 5 层排除的路径。Git 全局排除——core.excludesFile来自~/.gitconfig或 XDG git config默认$XDG_CONFIG_HOME/git/ignore仅当项目是带 config 的 git 仓库时才查询。对文件而言内置后缀过滤.png、.o、.db等fast 模式追加压缩包、媒体、lockfile、.min.js等与 fast 模式的文件名/子串过滤运行在忽略文件之前最大文件大小上限则运行在忽略文件之后。以上几类过滤均无法通过.cbmignore覆盖。符号链接symlink永远被跳过。各层在源码中的落点内置目录列表ALWAYS_SKIP_DIRS[]定义了 60 个无条件跳过目录——VCS.git/.hg/.svn、IDE、Python/JS/TS 工具链缓存、构建产物、语言缓存、部署目录等见 src/discover/discover.cFAST_SKIP_DIRS[]追加了generated、fixtures、testdata、docs、examples、third_party、migrations、tools等仅在 moderate/fast 模式跳过的目录见 src/discover/discover.c。索引模式枚举定义见 src/discover/discover.hCBM_MODE_FULL0、CBM_MODE_MODERATE1、CBM_MODE_FAST2代码以“非 FULL”启用追加过滤。后缀 / 文件名 / 子串过滤ALWAYS_IGNORED_SUFFIXES[]~、.pyc、.o、.png、.db、.sqlite3等见 src/discover/discover.cFAST_IGNORED_SUFFIXES[]压缩包、音视频、.min.js/.min.css、密钥证书、.patch等见 src/discover/discover.cFAST_SKIP_FILENAMES[]LICENSE、CHANGELOG、各语言 lockfile 等见 src/discover/discover.c。判定入口 API 见 src/discover/discover.h。安全核心is_safety_core_dir明确列出.gitVCS 内部数据与info/exclude来源、node_modules会让发现过程爆炸、.worktrees与.claude-worktrees同一仓库的并行 checkout索引会造成整库内容重复并注明“仓库提交的.cbmignore绝不能击败这些 OOM/安全跳过”见 src/discover/discover.c。目录判定逻辑should_skip_directory按“内置跳过 →.cbmignore解除尝试 → 仓库.gitignore→ 嵌套.gitignore→.cbmignore正向/否定 → git 全局排除”的次序实现见 src/discover/discover.c。文件判定与原因分类file_skip_reason返回“为何不索引该文件”的字符串gitignore/cbmignore/skip-list/ignored-suffix/fast-pattern/size-cap见 src/discover/discover.c实现语义与布尔判定完全一致。发现 API 与配置项cbm_discover_opts_t中.cbmignore对应字段名为ignore_file注释即 “path to .cbmignore file, or NULL”与mode、max_file_size并列见 src/discover/discover.h。四、否定!语义与当前行为边界文档对否定语义给出了精确的三层描述.cbmignore内部标准 gitignore 语义pattern 从上到下求值最后一个匹配生效因此!pattern可把更早一行排除的内容重新包含回来。父目录剪枝与 git 相同的注意事项目录被排除后遍历不会下探进入它内部——无法重新包含一个“父目录已被排除”的文件。若确实需要其中的部分内容请否定目录本身例如先排除dir/再通过否定让遍历进入后按需保留。跨层级.cbmignore否定可覆盖git 全局排除层也可解除普通内置跳过目录。例如~/.config/git/ignore忽略了*.sql但本项目的 SQL 需要被索引在.cbmignore中加!*.sql即可。否定仍然不能覆盖安全核心四目录.git、node_modules、.worktrees、.claude-worktrees、仓库.gitignore/info/exclude、嵌套.gitignore、内置后缀/文件名过滤以及大小上限。测试用例交叉验证上述语义在 tests/test_discover.c 中有直接覆盖.cbmignore否定可救回被 git 全局排除的文件!rescued.go见 tests/test_discover.c!obj/可解除内置ALWAYS_SKIP目录issue #500 场景见 tests/test_discover.c!src/target/、!docs/分别验证只解除指定嵌套目录与 fast 模式追加目录见 tests/test_discover.c 与 tests/test_discover.cobj/\n!obj/与!obj/\nobj/两种顺序验证“最后匹配生效”见 tests/test_discover.c非 git 仓库场景下.cbmignore依然独立生效见 tests/test_discover.c。规划的后续工作文档披露了一个明确后续计划辅助文件系统遍历器auxiliary filesystem walkers将复用与发现阶段完全相同的 ignore 判定谓词使所有代码路径看到一致的忽略决策统一次要在后续 issue 中跟踪。这意味着“不同遍历入口对.cbmignore的采纳可能不一致”的现状未来会收敛为单一决策源。五、验证如何确认.cbmignore确实生效文档提供了标准自检方法发现阶段被跳过的目录子树会出现在index_repository响应的excluded字段中{dirs: [最多 25 个路径], count: 总数量, truncated: 是否截断}dirs至多 25 个被跳过子树的示例相对路径count跳过的目录子树总数不会因截断而低估truncateddirs是否因超过示例数量而被截断。这一契约在源码层有完整对应cbm_discover_ex/cbm_discover_ex2在遍历中收集被跳过的目录子树内置ALWAYS_SKIP/FAST_SKIP目录 gitignore 命中以相对路径数组交给调用方见 src/discover/discover.hcbm_discover_ex2还能逐文件上报“刻意不索引”的原因reason 字符串及CBM_DISCOVER_IGNORED_CAP上限见 src/discover/discover.h。这类忽略在仓库中属**设计使然BY DESIGN**而非故障。实操建议修改.cbmignore后触发重新索引核对index_repository响应中的excluded目录子树与单文件 ignored 原因列表——若原因出现cbmignore即证明该文件是被本文件排除的。六、最佳实践小结它是团队协作工具提交到仓库即全员共享索引规则列入.gitignore则保留个人排除习惯二者并行不悖。位置唯一只认仓库根目录的repo/.cbmignore子目录中无法追加或覆盖规则。善用否定、警惕父目录剪枝需要“忽略整个目录但保留其中个别内容”时否定要落在目录本身或更精确的子树路径上因为遍历不会进入已排除目录。不要对不可解除的层级抱有幻想安全核心四目录、仓库/嵌套.gitignore、内置后缀/文件名过滤与大小上限都不受否定影响不必浪费规则去尝试。依赖excluded自检每次改动后通过index_repository响应的excluded目录列表与 ignored 文件原因双重核对保证索引范围符合预期。参考文件索引核心文档docs/cbmignore.md模式匹配引擎解析、glob 匹配、合并src/discover/gitignore.c发现与过滤实现内置列表、优先级、原因分类src/discover/discover.c发现 API 与排除上报契约src/discover/discover.h否定与优先级测试tests/test_discover.c分层忽略总述README.md.cbmignore作为根控制文件的处理src/pipeline/pipeline_incremental.c【免费下载链接】codebase-memory-mcpHigh-performance code intelligence MCP server. Indexes codebases into a persistent knowledge graph — average repo in milliseconds. 158 languages, sub-ms queries, 99% fewer tokens. Single static binary, zero dependencies.项目地址: https://gitcode.com/GitHub_Trending/co/codebase-memory-mcp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表