Pattern Filtering¶
Recursivist offers several complementary ways to control which files and directories appear. This guide explains each one and, importantly, how they interact.
The Four Filtering Mechanisms¶
| Mechanism | Option | Matches against |
|---|---|---|
| Directory exclusion | --exclude | Directory name |
| Extension exclusion | --exclude-ext | File extension |
| Include/exclude patterns | --include-pattern / --exclude-pattern | File name (glob or regex) |
| Ignore file | --ignore-file | File path, gitignore-style |
The distinction in the last column matters: include and exclude patterns test a file's name, not its path, whereas an ignore file matches paths. This determines which tool to reach for, as explained below.
Directory Exclusion¶
Exclude directories by name. Matching directories are pruned entirely and never descended into:
recursivist visualize --exclude node_modules --exclude .git --exclude venv
# or with repeated flags:
recursivist visualize --exclude node_modules --exclude .git
Extension Exclusion¶
Exclude files by extension. The leading dot is optional:
Include and Exclude Patterns¶
These options accept either glob patterns (the default) or regular expressions (with --regex), and match against each file's name — the basename, evaluated at every level of the tree.
# Exclude every JavaScript test file, anywhere in the tree
recursivist visualize --exclude-pattern "*.test.js" --exclude-pattern "*.spec.js"
# Exclude Python cache files
recursivist visualize --exclude-pattern "*.pyc"
# Keep only Markdown and Python files
recursivist visualize --include-pattern "*.md" --include-pattern "*.py"
Patterns match file names, not paths
Because patterns are tested against the file name only, a path-style pattern such as src/* or src/**/*.js will not match anything — file names never contain a /. A pattern like *.js, by contrast, matches .js files at any depth. To filter by location rather than by name, use a directory exclusion (--exclude src) or an ignore file (see below).
Glob syntax: * matches any run of characters, ? matches a single character, [abc] matches one listed character, and [!abc] matches one character not listed. With --regex, patterns follow Python's regular-expression syntax and are searched within the file name (anchor with ^ and $ for a full-name match):
recursivist visualize --exclude-pattern "^test_.*\.py$" --regex
recursivist visualize --exclude-pattern ".*\.(spec|test)\.(js|ts)$" --regex
Ignore Files¶
The --ignore-file option reads a gitignore-style file and applies its patterns to each file's path. This is the path-aware mechanism. Matching is delegated to pathspec's gitignore implementation, so it follows the full gitignore specification: anchoring, the ** wildcard, directory-only patterns (a trailing /), negation (a leading !, with last-match-wins), character classes, and backslash escapes.
recursivist visualize --ignore-file .gitignore
recursivist visualize --ignore-file .recursivist-ignore
The leading dot in the name is optional: --ignore-file gitignore resolves to .gitignore when that file is present, so both spellings work.
Like Git, ignore files are discovered at every level of the tree, and each is evaluated relative to the directory that contains it rather than to the scan root. So an anchored pattern such as /build in a nested .gitignore matches only inside that subdirectory; a deeper ignore file's verdict overrides a shallower one for the same path.
An example .recursivist-ignore:
# Dependencies and build output
node_modules/
dist/
build/
# Logs and caches
*.log
.cache/
# But keep an important generated file
!build/manifest.json
Order of Precedence¶
When several mechanisms are combined, Recursivist resolves them per file as follows:
- Directory exclusions (
--exclude) prune matching directories before anything else. - Include patterns (
--include-pattern): if any are set, a file must match at least one, or it is dropped. - Exclude patterns (
--exclude-pattern): a matching file is removed — this overrides include patterns. - Excluded extensions (
--exclude-ext): a matching file is removed — this also overrides include patterns. - Include match wins over ignore files: a file that matched an include pattern is kept even if an ignore-file pattern would exclude it.
- Ignore-file patterns (
--ignore-file) are applied last to anything still undecided.
Note
This means include patterns do not override everything. Explicit exclude patterns and excluded extensions take priority over includes; include patterns only take priority over ignore-file patterns.
Combining Filters¶
The mechanisms compose cleanly:
recursivist visualize \
--exclude node_modules --exclude .git --exclude build \
--exclude-ext .pyc --exclude-ext .log \
--exclude-pattern "*.test.js" \
--include-pattern "*.js" --include-pattern "*.md" \
--ignore-file .gitignore
Same Behavior Across Commands¶
Every filtering option works identically with visualize, export, and compare:
recursivist export --format md --include-pattern "*.py" --exclude-pattern "test_*.py"
recursivist compare dir1 dir2 --exclude node_modules --exclude .git --exclude-ext ".log"
Examples¶
# Documentation files only
recursivist visualize --include-pattern "*.md" --include-pattern "*.rst" --include-pattern "*.txt"
# Exclude generated and minified assets
recursivist visualize --exclude dist --exclude build --exclude-ext .min.js --exclude-ext .map
# Backend source, excluding tests (regex)
recursivist visualize --include-pattern ".*\.py$" --exclude-pattern "test_.*\.py$" --regex
For a focused reference on glob and regex syntax, see Pattern Matching.