# How to Configure Ignore Patterns for Code Parsing in Code-Graph-RAG

> Learn to configure ignore patterns for code parsing in Code-Graph-RAG using built-in rules .gitignore and .cgrignore files for efficient code analysis.

- Repository: [Vitali Avagyan/code-graph-rag](https://github.com/vitali87/code-graph-rag)
- Tags: how-to-guide
- Published: 2026-08-18

---

**Code-Graph-RAG uses a three-layer ignore system—built-in constants, `.gitignore`, and project-specific `.cgrignore` files—controlled by `should_skip_path()` in [`codebase_rag/utils/path_utils.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/utils/path_utils.py) to filter files during repository traversal.**

When building knowledge graphs from source code, the `vitali87/code-graph-rag` tool must distinguish between relevant source files and build artifacts. Understanding how to configure ignore patterns for code parsing in Code-Graph-RAG ensures that virtual environments, compiled binaries, and generated files do not pollute your graph while preserving the source code that matters.

## The Three-Layer Ignore System

The ignore architecture in Code-Graph-RAG operates through three distinct layers, each loaded and merged during initialization.

### Built-in Ignores

Located in [`codebase_rag/constants/languages.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/constants/languages.py) (lines 68-84 and 21-22), the constants `IGNORE_PATTERNS` and `IGNORE_SUFFIXES` provide baseline exclusions. These always skip directories like `node_modules`, `__pycache__`, and `bin`, along with file extensions such as `.pyc` and `.class`. These patterns are imported as `cs.IGNORE_PATTERNS` and `cs.IGNORE_SUFFIXES` and applied universally.

### Repository-Wide Ignores

The root `.gitignore` file follows standard gitwildmatch semantics and is parsed by `load_ignore_patterns()` in [`codebase_rag/config.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/config.py) (lines 44-45). Patterns ending with a trailing slash match directories only, allowing you to exclude entire subtrees like `.venv/` or `dist/` using familiar Git syntax.

### Project-Specific Ignores

For Code-Graph-RAG-specific rules without modifying version control, create a `.cgrignore` file. The function `load_cgrignore_patterns()` in [`codebase_rag/config.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/config.py) (lines 43-44) loads this file and merges it with `.gitignore` in `load_ignore_patterns()` (lines 47-55). This merge gives precedence to `.cgrignore` excludes while maintaining separate unignore contexts.

## How the Ignore Logic Works

The core decision engine resides in `should_skip_path()` within [`codebase_rag/utils/path_utils.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/utils/path_utils.py) (lines 27-65). When the repository walker encounters a path, it executes the following validation sequence:

1. **Suffix validation** – If the file extension appears in `cs.IGNORE_SUFFIXES`, the path is immediately skipped (line 35).
2. **Containment check** – The absolute path is verified to reside within the repository root (lines 38-44).
3. **Pattern matching** – The relative POSIX path (with trailing `/` for directories) is tested against `exclude_paths` via `matches_ignore_patterns()` (line 49). Matches trigger exclusion (line 50).
4. **Unignore reversal** – If the path matches an `unignore_paths` pattern, the skip is cancelled (lines 52-53).
5. **Directory descent control** – For directories, an unignore pattern matching contents forces the walker to descend (lines 55-61).
6. **Ignored directory parts** – Finally, `has_ignored_dir_part()` (lines 71-77) scans components for built-in ignored names like `bin` (except when under `src/`).

Additionally, `matches_test_path()` in [`codebase_rag/path_filters.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/path_filters.py) (lines 9-23) identifies test files using `cs.TEST_PATH_PATTERNS`, enabling optional exclusion of test code from dead-code analysis.

## Practical Configuration Methods

### Creating a .cgrignore File

Place a `.cgrignore` file at the repository root to add project-specific rules without altering `.gitignore`. The syntax mirrors Git's:

```text

# Exclude generated protobuf files

*.pb.go

# Exclude temporary folders

tmp/

# Unignore a specific generated file

!tmp/keep_this_generated.py

```

Important limitation: Unignore lines (`!pattern`) only affect patterns within the same file. A `.cgrignore` unignore cannot rescue a file excluded by `.gitignore`.

### Using CLI Exclude Flags

For temporary exclusions without file modifications, use the `--exclude` or `-e` flag when invoking the CLI (defined in [`codebase_rag/cli.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/cli.py)). These patterns are added to `exclude_paths` and passed directly to `should_skip_path()`:

```bash
cgr index --repo /path/to/project -e "generated/*" -e "*.log"

```

### Understanding Unignore Behavior

To "unignore" a file pattern already excluded by `.gitignore`, you cannot use `!` in `.cgrignore`. Instead, add an explicit include rule without the negation:

```text

# .gitignore contains: *.log

# .cgrignore to rescue important.log:

important.log    # ✅ Works as explicit include

!important.log   # ❌ Does not override .gitignore

```

## Summary

- Code-Graph-RAG employs built-in constants, `.gitignore`, and `.cgrignore` to filter files during graph construction.
- The `should_skip_path()` function in [`codebase_rag/utils/path_utils.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/utils/path_utils.py) implements a six-stage validation including suffix checks, pattern matching, and unignore logic.
- Create `.cgrignore` for project-specific rules that should not affect version control.
- Use CLI flags `--exclude` or `-e` for temporary exclusions without editing files.
- Unignore patterns (`!`) only work within their originating file and cannot override `.gitignore` exclusions.

## Frequently Asked Questions

### Can I override .gitignore patterns using .cgrignore?

No. Unignore lines (`!pattern`) in `.cgrignore` only cancel excludes defined within that same file. To include a file excluded by `.gitignore`, add the filename as a positive pattern in `.cgrignore` without the `!` prefix, effectively creating an explicit include that takes precedence.

### How do I exclude specific file types like logs or generated code?

Add patterns to `.cgrignore` using standard glob syntax. For example, `*.log` excludes all log files, while `generated/` excludes entire directories. For one-off executions, use the CLI flag `-e "*.log"` without modifying any files.

### What is the difference between .cgrignore and .gitignore in Code-Graph-RAG?

`.gitignore` is parsed for repository-wide exclusions following Git's semantics, while `.cgrignore` is specific to Code-Graph-RAG and loaded via `load_cgrignore_patterns()`. The latter allows you to add build artifacts or generated files to the graph exclusion list without polluting your version control ignore rules.

### How does Code-Graph-RAG handle test files?

Test files are identified by `matches_test_path()` in [`codebase_rag/path_filters.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/path_filters.py) using the `TEST_PATH_PATTERNS` constant. This classification enables the system to optionally exclude test code from the knowledge graph during dead-code analysis or other operations requiring production-only source code.