How to Use Ignore Patterns to Exclude Files and Directories from Code‑Graph‑RAG Analysis
Code‑Graph‑RAG uses a layered ignore system—built‑in patterns, .cgrignore files, .gitignore inheritance, and CLI flags—to filter out build artifacts, virtual environments, and other non‑source content before building the code graph.
The code‑graph‑rag repository implements a Git‑compatible ignore mechanism that prevents noisy files from polluting your retrieval‑augmented generation (RAG) graph. Understanding how to configure these patterns gives you precise control over what gets indexed and what gets skipped.
Core Components of Code‑Graph‑RAG Ignore Patterns
Built‑in IGNORE_PATTERNS in constants/languages.py
The foundation of CGR's filtering system is a frozen set of directory names, file suffixes, and glob patterns defined in codebase_rag/constants/languages.py. This constant—IGNORE_PATTERNS—includes standard exclusions like:
.git,.hg,.svnnode_modules,__pycache__,.pytest_cachevenv,.venv,env,.toxbuild,dist,target,out
These patterns are applied automatically to every repository walk. The file also defines IGNORE_SUFFIXES for file extensions that should never be parsed.
Git‑Wildmatch Pattern Matching in path_utils.py
The actual matching logic resides in codebase_rag/utils/path_utils.py. Key functions include:
compiled_ignore_spec(patterns)– Compiles a list of patterns into aPathSpecusingGITWILDMATCH_STYLE, giving you full Git‑ignore semanticsmatches_ignore_patterns(path, spec)– Tests whether a specific path matches any pattern in the compiled specshould_skip_path(path, repo_root, compiled_spec, unignore_spec)– The primary gatekeeper used during directory traversal
The should_skip_path function (lines 111–124) applies checks in order: file suffix filtering, repository root containment, ignore pattern matching, and finally unignore pattern evaluation.
Unignore Support for Selective Inclusions
CGR supports unignore patterns prefixed with !. These are handled separately:
- Stored in
unignore_pathslist - Evaluated by
unignore_could_match_within(path, unignore_paths)to determine if a directory should be kept (because an unignore might match a descendant)
This ensures that ignored directories aren't pruned prematurely when they contain files you explicitly want to keep.
Configuration Methods for Ignore Patterns
Method 1: Project‑Level .cgrignore Files
Create a .cgrignore file at your repository root with Git‑ignore syntax:
# Ignore generated documentation
docs/_build/
site/
# Ignore local configuration but keep example
config/local.yml
!config/local.example.yml
# Ignore all log files
*.log
CGR automatically discovers and loads .cgrignore during ingestion. If no .cgrignore exists, CGR falls back to the repository's .gitignore file.
Method 2: CLI --exclude Flag
Pass patterns directly via command line in codebase_rag/cli.py:
cgr ingest \
--repo /path/to/project \
--exclude "tmp,cache,__pycache__" \
--output graph.json
The --exclude value is parsed as comma‑separated patterns and merged into the active ignore set before graph construction begins.
Method 3: Environment Variable CGR_IGNORE_DIRS
As demonstrated in realtime_updater.py, you can set patterns via environment:
export CGR_IGNORE_DIRS="node_modules,dist,coverage"
cgr ingest --repo /path/to/project
The updater forwards CGR_IGNORE_DIRS_ENV to subprocesses, ensuring consistent ignore behavior across incremental updates.
Method 4: Programmatic Modification
For custom scripts or tests, modify the constants directly:
from codebase_rag.constants import languages as cs
# Add custom patterns to the built‑in set
cs.IGNORE_PATTERNS = cs.IGNORE_PATTERNS | {"my_temp_dir", "*.generated.py"}
cs.IGNORE_SUFFIXES = cs.IGNORE_SUFFIXES | {".tmp", ".bak"}
This pattern appears in the CGR test suite for scenario‑specific filtering.
Practical Code Examples
Checking Whether a Path Would Be Skipped
from pathlib import Path
from codebase_rag.utils.path_utils import (
compiled_ignore_spec,
should_skip_path
)
from codebase_rag.constants.languages import IGNORE_PATTERNS
# Compile the default ignore patterns
spec = compiled_ignore_spec(IGNORE_PATTERNS)
repo_root = Path("/home/user/myproject")
# Test a specific path
test_path = Path("/home/user/myproject/node_modules/lodash/index.js")
would_skip = should_skip_path(test_path, repo_root, spec, None)
print(f"Would skip {test_path}: {would_skip}") # True
Creating a Custom Ignore Spec with Unignore Rules
from pathlib import Path
from codebase_rag.utils.path_utils import compiled_ignore_spec
# Mix ignore and unignore patterns
raw_patterns = [
"build/", # Ignore build directory
"!build/release/", # But keep release subdirectory
"*.min.js", # Ignore minified JS
"!vendor/", # Exception: keep vendor folder
]
spec = compiled_ignore_spec(raw_patterns)
# Test matching
from pathspec import PathSpec
match = spec.match_file("build/release/app.js") # True (unignore works)
match = spec.match_file("build/debug/app.js") # False (still ignored)
Loading and Merging Multiple Ignore Sources
from pathlib import Path
from codebase_rag.utils.path_utils import load_ignore_patterns
# Prioritized loading: .cgrignore first, then .gitignore
patterns = load_ignore_patterns(
repo_path=Path("/path/to/repo"),
prefer_cgrignore=True
)
# Returns list of patterns found, ready for compilation
How Directory Pruning Works
The function should_keep_dir(path, unignore_paths) (in path_utils.py) optimizes traversal by pruning entire directories when safe. A directory is pruned only when:
- Its name matches an ignore pattern, and
- No unignore pattern could possibly match any descendant
This prevents the expense of walking into node_modules or __pycache__ while still respecting selective unignore rules that might target nested files.
Summary
IGNORE_PATTERNSinconstants/languages.pyprovides the default exclusion set for common build tools and package managerspath_utils.pyimplements Git‑compatible matching viaPathSpecwithGITWILDMATCH_STYLE.cgrignorefiles override defaults with project‑specific rules;.gitignoreserves as automatic fallback--excludeCLI flag andCGR_IGNORE_DIRSenvironment variable enable ad‑hoc filtering without file changes- Unignore patterns (
!pattern) rescue specific files or subdirectories from blanket ignores
Frequently Asked Questions
What is the difference between .cgrignore and .gitignore in Code‑Graph‑RAG?
Code‑Graph‑RAG checks for .cgrignore first and uses it exclusively if found. Only when .cgrignore is absent does CGR fall back to .gitignore. This design lets you maintain RAG‑specific exclusions separate from version control rules—for example, ignoring API documentation that exists in Git but shouldn't be embedded in your code graph.
Can I use glob patterns and negation in my ignore files?
Yes. CGR uses Git's wildmatch specification through the pathspec library. You can use * for wildcards, ** for recursive matching, ? for single characters, and ! at the start of a line to negate previous patterns. Trailing slashes match directories only. These rules are identical to standard .gitignore behavior.
Why does Code‑Graph‑RAG still index some files in an ignored directory?
This occurs when you have an unignore pattern targeting specific files or subdirectories. CGR's should_keep_dir function detects whether any unignore could match a descendant; if so, it keeps the directory open for traversal. Check your .cgrignore or .gitignore for lines starting with ! that might be resurrecting content you intended to exclude.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →