Gemini CLI 的 .geminiignore 文件忽略机制:语法规则、配置项与源码实现
【免费下载链接】gemini-cliAn open-source AI agent that brings the power of Gemini directly into your terminal.项目地址: https://gitcode.com/GitHub_Trending/gemi/gemini-cli
本文基于 gemini-cli 官方文档与仓库源码,完整讲解.geminiignore文件的作用范围、glob 语法规则、创建与修改方法,并结合FileDiscoveryService、GitIgnoreParser、IgnoreFileParser等核心实现源码,剖析 .gitignore 与 .geminiignore 规则是如何合并、匹配与生效的。读完本文,你可以在项目中正确配置文件过滤规则,并理解每一项配置背后的底层匹配逻辑。
.geminiignore 是什么
Gemini CLI 内置了自动忽略文件的能力,其行为类似于 Git 使用的.gitignore和 Gemini Code Assist 使用的.aiexclude。将路径添加到项目根目录的.geminiignore文件后,所有支持该特性的工具(文件查找、@引用、目录列表等)都会在执行操作时排除这些匹配的文件和目录;但被忽略的文件对 Git 等其他服务依然可见——也就是说,.geminiignore只影响 Gemini CLI 的文件发现行为,不改变 Git 的跟踪状态。
这个文件名常量定义在 constants.ts 中:
export const GEMINI_IGNORE_FILE_NAME = '.geminiignore';它与 文件管理教程 中“Control what Gemini sees”一节是配套能力:当你有.env、数据库导出等敏感文件,希望它们对 AI 隐藏而又不想在 Git 中忽略时,.geminiignore正是为此设计的。
.geminiignore 的语法规则
.geminiignore绝大部分情况下遵循.gitignore文件的约定:
| 规则 | 说明 |
|---|---|
空行与#开头的行 | 被忽略,用作注释或占位 |
| 标准 glob 模式 | 支持*、?、[]等通配符 |
行尾加/ | 仅匹配目录(如/archive/) |
行首加/ | 将路径锚定到.geminiignore文件所在目录的相对位置 |
!前缀 | 否定一条模式,把已被排除的文件/目录重新纳入 |
需要注意的最后一条规则是:修改.geminiignore文件可以随时进行,但必须重启 Gemini CLI 会话才能让变更生效。这一点在源码中有直接印证——fileFiltering下的配置项均标记了requiresRestart: true(见后文“相关配置项”一节),会话启动时才会重新加载忽略规则。
如何创建和使用 .geminiignore
启用.geminiignore只需两步:
- 在项目根目录创建一个名为
.geminiignore的文件; - 在其中逐行写入要忽略的路径或文件名,例如
/archive/或apikeys.txt。
要移除某条忽略规则,直接删除对应行即可。
.geminiignore 示例
忽略整个目录(含所有子目录)与单个文件:
# Exclude your /packages/ directory and all subdirectories /packages/ # Exclude your apikeys.txt file apikeys.txt使用*通配符批量忽略:
# Exclude all .md files *.md使用!从排除中“捞回”特定文件:
# Exclude all .md files except README.md *.md !README.md一个更贴近实战的敏感文件示例(摘自 file-management 教程):
.env local-db-dump.sql private-notes.md哪些工具会遵守 .geminiignore
文档中给出的典型场景是@文件引用:使用@命令分享文件时,.geminiignore中匹配的路径会被自动排除。从源码结构看,遵守该规则的能力由统一的文件过滤服务提供,被多个核心工具复用:
ls与glob工具:在 ls.ts 与 glob.ts 中,工具调用config.getFileService()获得FileDiscoveryService实例,并调用filterFilesWithReport()对候选路径列表做过滤,返回被忽略文件数量报告;@引用解析:提示词处理层通过 atFileProcessor.ts 解析@文件引用,其候选文件来源即受文件过滤服务约束;- 目录结构采集:getFolderStructure.ts 在生成项目目录结构时同样应用了
respectGitIgnore/respectGeminiIgnore选项; - 沙箱:从源码结构看,sandboxManager.ts 与 Linux/Windows 沙箱参数构建器(bwrapArgsBuilder.ts)也引用了
.geminiignore路径,用于在沙箱环境中约束文件访问面。
源码解析:FileDiscoveryService 的统一过滤模型
文件过滤的总入口是 fileDiscoveryService.ts 中的FileDiscoveryService类。它在构造函数中完成三类过滤器的装配:
constructor(projectRoot: string, options?: FilterFilesOptions) { // ... if (isGitRepository(this.projectRoot)) { this.gitIgnoreFilter = new GitIgnoreParser(this.projectRoot); } this.geminiIgnoreFilter = new IgnoreFileParser( this.projectRoot, GEMINI_IGNORE_FILE_NAME, ); // ... // 创建组合解析器: .gitignore + .geminiignore + custom ignore this.combinedIgnoreFilter = new GitIgnoreParser( this.projectRoot, // customPatterns 放最后,确保其能覆盖 geminiPatterns [...geminiPatterns, ...customPatterns], ); }从这段构造逻辑可以读出几个关键事实:
- 三类规则来源:
.gitignore(仅当项目根是 Git 仓库时启用)、.geminiignore、以及用户通过customIgnoreFilePaths自定义的额外忽略文件; - 组合优先级:在 Git 仓库中,
.geminiignore与自定义规则以“额外模式”的形式追加到GitIgnoreParser的最后。由于ignore库中后加入的模式覆盖先加入的模式,.geminiignore / 自定义规则天然拥有高于 .gitignore 的优先级; - 非 Git 仓库的退化路径:若项目不是 Git 仓库,服务改用
IgnoreFileParser直接组合.geminiignore与自定义规则,保证没有.gitignore时.geminiignore依然独立生效; - 符号链接防绕过:内部方法
_shouldIgnore()会对路径做lstatSync检测,若为符号链接则解析真实目标路径并再次执行过滤,防止通过软链引用被忽略目录。
对外 API 上,filterFiles()提供基础过滤(注意目录路径需带结尾/才能正确匹配目录型模式,如dist/),filterFilesWithReport()额外返回{ filteredPaths, ignoredCount }报告,shouldIgnoreFile()/shouldIgnoreDirectory()提供单点查询,getIgnoredPaths()则会并发遍历目录树,返回所有“应被忽略”的绝对路径(遇到被忽略的目录即剪枝,不再深入)。
配置如何注入到过滤服务
FileDiscoveryService的选项来自全局配置。在 config.ts 中:
getFileService(): FileDiscoveryService { if (!this.fileDiscoveryService) { this.fileDiscoveryService = new FileDiscoveryService(this.targetDir, { respectGitIgnore: this.fileFiltering.respectGitIgnore, respectGeminiIgnore: this.fileFiltering.respectGeminiIgnore, customIgnoreFilePaths: this.fileFiltering.customIgnoreFilePaths, }); } return this.fileDiscoveryService; }getFileService()采用懒加载单例,ls、glob等工具每次执行文件过滤时都拿到同一个实例,保证规则集在会话内一致。这也解释了文档中“必须重启会话才能应用变更”的原因:规则在实例创建时固化,运行中不会热重载。
源码解析:两个模式解析器的分工
IgnoreFileParser:轻量版 .geminiignore 解析
ignoreFileParser.ts 负责直接读取项目根下的.geminiignore文件:
return (content ?? '') .split(/\r\n|\n|\r/) .map((p) => p.trim()) .filter((p) => p !== '' && !p.startsWith('#'));可以看到它对文档所述规则的直接实现:按\r\n、\n、\r三种换行拆分(兼容 Windows/macOS 旧格式),去除首尾空白,过滤空行和#注释行,其余模式原样交给ignore库做 glob 匹配。文件不存在时仅打印 debug 日志并返回空规则集,不会报错。构造参数还支持传入多个文件名,且“列表中越靠前的文件优先级越高”——这为customIgnoreFilePaths的数组顺序语义提供了实现依据。
GitIgnoreParser:完整的 .gitignore 语义实现
gitIgnoreParser.ts 是更复杂的解析器,它承担了.gitignore的完整语义,并把.geminiignore模式作为extraPatterns并入:
- 全局排除文件:加载
.git/info/exclude中的模式(loadPatternsForFile()会识别该特殊路径,将其基准目录视为项目根); - 嵌套 .gitignore 处理:
processPatterns()针对a/b/.gitignore中定义的模式做目录锚定变换——/c变为/a/b/c、裸名c变为/a/b/**/c、c/d变为/a/b/c/d,与 Git 官方行为一致; - 层级剪枝优化:
isIgnored()中从项目根到目标文件的每一层父目录都会被逐层检查,一旦某层祖先目录已命中忽略规则即提前终止(“父目录被忽略则其子项自动被忽略”); - 根目录永不忽略:归一化路径为空或
/时直接返回false,避免规则误伤项目根; - 固定忽略
.git:每次匹配前都ignore().add('.git'),确保 Git 内部元数据不参与文件发现; .geminiignore的最终裁定权:方法末尾ig.add(this.processedExtraPatterns).ignores(normalizedPath)把额外模式放在最后追加,使.geminiignore的规则可以在最终判定阶段覆盖前面的.gitignore结果。
相关配置项
在 settingsSchema.ts 中,context.fileFiltering对象定义了以下与.geminiignore直接相关的设置(也可在 settings.md 与 configuration.md 中查阅):
| 配置键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
context.fileFiltering.respectGitIgnore | boolean | true | 搜索时是否遵守.gitignore文件 |
context.fileFiltering.respectGeminiIgnore | boolean | true | 搜索时是否遵守.geminiignore文件 |
context.fileFiltering.customIgnoreFilePaths | string[] | [] | 额外的忽略文件路径,优先级高于.geminiignore和.gitignore;数组中靠前的文件优先于靠后的文件 |
三个配置项均标记requiresRestart: true,即修改后需要重启会话生效。一个典型的 settings.json 片段:
{ "context": { "fileFiltering": { "respectGeminiIgnore": true, "customIgnoreFilePaths": ["./secrets.ignore"] } } }注意customIgnoreFilePaths的语义是“叠加一层更高优先级的排除规则”,而非替换:从FileDiscoveryService构造函数中[...geminiPatterns, ...customPatterns]的拼接顺序看,自定义文件的模式追加在最后、覆盖力最强,适合放置团队级或机器级的强制排除清单。
小结
.geminiignore是 Gemini CLI 中在 Git 之上叠加的第二层文件过滤机制:语法几乎完全兼容.gitignore(空行/#注释、*?[]glob、结尾/限定目录、开头/锚定相对位置、!否定),文件创建在项目根目录即可生效,修改后重启会话加载。其底层由 FileDiscoveryService 统一调度,配合 GitIgnoreParser 与 IgnoreFileParser 完成嵌套 .gitignore 锚定、.git/info/exclude加载、符号链接解析与规则优先级合并,并被ls、glob、@引用解析、目录结构采集乃至沙箱构建等多个模块复用。理解了这套实现,你就能准确预期“某个文件到底会不会出现在工具结果里”,并借助customIgnoreFilePaths定制团队统一的过滤策略。
【免费下载链接】gemini-cliAn open-source AI agent that brings the power of Gemini directly into your terminal.项目地址: https://gitcode.com/GitHub_Trending/gemi/gemini-cli
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考