菜单

文件遍历与过滤

相关源文件

此页面记录了 ripgrep 中的文件遍历和过滤系统,它决定了哪些文件会被搜索以及哪些会被忽略。有关如何在文件内执行实际搜索的信息,请参阅 核心搜索引擎

概述

文件遍历和过滤系统负责

  1. 递归遍历目录以识别文件
  2. 应用各种过滤规则来确定哪些文件应被处理
  3. 将符合条件的文件馈送给搜索引擎

此功能主要实现在 ignore crate 中,它提供了一个快速、可定制的目录迭代器,具有复杂的过滤能力。

来源:crates/ignore/src/walk.rs433-482 crates/ignore/src/dir.rs402-532

目录遍历器

目录遍历器负责递归遍历目录以查找文件。它同时提供顺序和并行遍历选项。

遍历器类型

Ripgrep 提供两种类型的目录遍历器

  1. 顺序遍历器(Walk:单线程逐个遍历目录
  2. 并行遍历器(WalkParallel:使用多线程遍历目录以提高性能

构建遍历器

两个遍历器都使用 WalkBuilder 构建,它提供了一套丰富的配置选项

来源:crates/ignore/src/walk.rs483-904 crates/ignore/src/walk.rs30-117

配置选项

The WalkBuilder 支持许多选项来控制遍历和过滤

选项默认描述
hidden(bool)true忽略隐藏的文件和目录
ignore(bool)true尊重 .ignore 文件
git_ignore(bool)true尊重 .gitignore 文件
git_global(bool)true尊重全局 git 忽略文件
git_exclude(bool)true尊重 .git/info/exclude 文件
parents(bool)true尊重父目录中的忽略文件
max_depth(Option<usize>)None最大递归深度
max_filesize(Option<u64>)None要搜索的最大文件大小
follow_links(bool)false跟随符号链接
threads(usize)0 (自动)并行遍历的线程数
same_file_system(bool)false不跨越文件系统边界

来源:crates/ignore/src/walk.rs519-905

目录条目

遍历器找到的每个文件都由一个 DirEntry 表示,它提供

  • 路径信息
  • 文件元数据
  • 文件类型信息
  • 相对于根目录的深度
  • 关联的错误(如果有)

来源:crates/ignore/src/walk.rs30-117

过滤机制

过滤系统决定哪些文件应被包含或排除在搜索之外。Ripgrep 按照特定的优先级顺序应用过滤器。

过滤器优先级

过滤器按以下顺序应用(优先级从高到低)

  1. 覆盖规则 - 显式的包含/排除模式
  2. 自定义忽略文件 - 用户指定的忽略文件
  3. .ignore 文件 - 项目特定的忽略文件
  4. .gitignore 文件 - 标准的 git 忽略模式
  5. .git/info/exclude 文件 - 仓库特定的 git 排除文件
  6. 全局 gitignore 文件 - 用户的全局 git 忽略文件
  7. 文件类型过滤器 - 基于文件扩展名
  8. 隐藏文件过滤器 - 名称以 . 开头的文件
  9. 二进制文件检测 - 跳过二进制文件
  10. 文件大小限制 - 跳过大于配置限制的文件

如果文件匹配了白名单模式(覆盖或文件类型),则无论其他忽略规则如何,都会包含该文件。如果它匹配了忽略模式,则会被排除。

来源:crates/ignore/src/dir.rs402-532 crates/ignore/src/walk.rs433-482

忽略文件结构

Ignore 结构维护了一个目录匹配器的层次结构

每个目录都有自己的匹配器,该匹配器组合了所有忽略源的模式。当遇到一个文件时,它会与适当目录的匹配器进行匹配。

来源:crates/ignore/src/dir.rs94-145 crates/ignore/src/dir.rs142-163

Gitignore 支持

Ripgrep 完全支持 gitignore 语义,与 git 本身实现兼容。

Gitignore 语义

实现遵循 git 的模式匹配规则

  • 不带 / 的模式匹配任何目录下的文件
  • 带有前导 / 的模式仅从根目录开始匹配
  • 带有尾随 / 的模式仅匹配目录
  • 模式可以通过 ! 前缀进行否定
  • ** 匹配零个或多个目录

来源:crates/ignore/src/gitignore.rs435-517

匹配过程

在评估文件是否应被忽略时

  1. 先检查覆盖规则
  2. 从最具体的目录到最不具体的目录评估模式
  3. 最后一个匹配的模式决定结果
  4. 如果匹配了白名单模式,则包含该文件
  5. 如果匹配了忽略模式,则排除该文件
  6. 如果没有匹配任何模式,并且至少存在一个白名单,则排除该文件

来源:crates/ignore/src/dir.rs365-408 crates/ignore/src/walk.rs433-482

文件类型匹配

Ripgrep 支持通过扩展名或模式对文件进行类型过滤。

默认类型

系统预定义了涵盖多种语言和格式的文件类型

类型扩展
rust*.rs
c*.{c,h}
cpp*.{cpp,cc,cxx,h,hh,hpp,hxx}
js*.{js,jsx,vue,cjs,mjs}
go*.go
py*.{py,pyi}
......

默认配置中定义了 200 多种文件类型。

来源:crates/ignore/src/default_types.rs12-329

文件类型选择

文件类型可以选择或排除,以包含或排除特定类型

可以使用 glob 模式定义自定义文件类型

--type-add='custom:*.{foo,bar}'

来源:crates/ignore/src/types.rs308-443

覆盖规则

覆盖规则提供了一种显式包含或排除文件的方式,其优先级高于所有其他过滤器。

覆盖模式

覆盖模式使用与 gitignore 相同的语法,但语义相反

  • 不带 ! 的模式用于显式包含文件(白名单)
  • ! 的模式用于显式排除文件(黑名单)

这与 gitignore 语义相反,在 gitignore 中,不带 ! 的模式会排除文件。

--include='*.rs'      # Include only Rust files
--exclude='**/test/*' # Exclude test directories

来源:crates/ignore/src/overrides.rs96-109

二进制文件检测

Ripgrep 可以检测并特殊处理二进制文件,避免搜索可能引起显示问题的那些内容。

检测策略

处理二进制文件的三种策略

  1. - 无二进制检测,搜索所有文件
  2. 退出 - 检测到二进制字节时停止搜索
  3. 转换 - 将二进制字节替换为行终止符

默认是,但大多数用户会将 ripgrep 配置为使用退出,以避免搜索二进制文件。

检测通常基于空字节(0x00)的存在,这是识别二进制文件的常见启发式方法。

来源:crates/searcher/src/searcher/mod.rs54-118 crates/line_buffer.rs42-70

文件遍历和过滤系统在文件通过所有过滤检查后,将其馈送给搜索引擎组件。

搜索引擎可以进一步配置以特殊方式处理某些文件内容

  • 将文件从各种编码转码为 UTF-8
  • 二进制内容的特殊处理
  • 逐行或多行搜索模式

来源:crates/searcher/src/searcher/mod.rs568-567

性能考量

文件遍历和过滤系统旨在实现高吞吐量

  1. 并行遍历 - 使用多线程加速目录遍历
  2. 高效的过滤器应用 - 按优先级顺序应用过滤器,并在可能的情况下进行短路
  3. 缓存 - 父目录的忽略匹配器会被重用于子目录
  4. 内存映射 - 在适当的情况下可用于大文件内存映射

过滤规则会尽可能早地应用,以避免不必要的文件操作和模式匹配。

来源: crates/ignore/src/walk.rs595-607 crates/ignore/src/dir.rs199-227

定制

Ripgrep 提供了多种自定义文件遍历和过滤的方式

命令行选项

选项描述
--files仅列出将要搜索的文件
--type=[TYPE]仅搜索与 TYPE 匹配的文件
--type-not=[TYPE]不要搜索与 TYPE 匹配的文件
--type-add=[TYPE:GLOB]添加新的文件类型定义
--glob=[GLOB]包含或排除与 GLOB 匹配的文件
-g, --glob=[GLOB]与 --glob 相同
--iglob=[GLOB]包含/排除与 GLOB 匹配的文件(不区分大小写)
--ignore-file=[PATH]指定额外的忽略文件
-p, --no-ignore-parent不尊重父目录中的忽略文件
--hidden搜索隐藏的文件和目录
--no-ignore不尊重任何忽略文件
--no-ignore-vcs不尊重版本控制忽略文件
--no-ignore-global不尊重全局忽略文件
--follow跟随符号链接
-L, --follow与 --follow 相同
--max-depth=[NUM]最多深入 NUM 个目录

配置文件

用户可以创建配置文件来设置默认选项

  • 全局配置: $HOME/.ripgreprc
  • 项目配置: .ripgreprc 在项目目录中

这些可以指定默认文件类型、忽略模式和搜索行为。

来源: crates/ignore/src/walk.rs614-816