# How to Configure Ignore Patterns for Large Monorepos in Code‑Graph‑RAG

> Learn to configure ignore patterns for large monorepos in Code-Graph-RAG using .cgrignore files and CLI flags for efficient file filtering and indexing.

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

---

**Code‑Graph‑RAG uses a `.cgrignore` file with git‑wildmatch syntax and optional CLI `--exclude` flags to filter files in large repositories, compiling patterns via `pathspec.PathSpec` for efficient indexing.**

When working with large monorepos, indexing every file can severely impact performance and pollute the knowledge graph with generated artifacts. The `vitali87/code-graph-rag` repository provides a flexible ignore-pattern system that lets you configure exactly which files and directories get excluded, using familiar `.gitignore`-style semantics processed by the engine in [`codebase_rag/utils/path_utils.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/utils/path_utils.py).

## Creating the `.cgrignore` Configuration File

To configure ignore patterns for large monorepos, create a `.cgrignore` file at the repository root. This file follows the same semantics as a standard `.gitignore`, where each line represents a pattern, lines starting with `#` indicate comments, and blank lines are ignored.

Place your exclusion rules in this file to permanently filter directories like vendor trees or generated code across all indexing operations.

## Understanding Git‑Wildmatch Pattern Semantics

The pattern matcher uses the `gitwildmatch` style from the `pathspec` library, as implemented in the `compiled_ignore_spec` logic. Understanding these rules ensures your exclusions target the correct files without accidentally filtering source code.

### Bare Names vs. Anchored Patterns

Bare names like `vendor` match any file or directory named vendor at any depth in the tree. Patterns containing a slash, such as `/generated`, are anchored to the repository root and only match at the top level, ignoring `src/generated` but catching `/generated`.

### Globbing Operators and Directory Matching

The syntax supports standard glob operators: `*` matches within a single path segment, `**` crosses directory boundaries recursively, and `?` matches a single character. Append a trailing slash (`build/`) to restrict matches to directories only, ensuring files named `build` are kept while the directory is excluded.

### Un‑ignoring with Negation Patterns

Lines beginning with `!` un‑ignore paths that would otherwise be excluded. However, negation only rescues files from built‑in default ignores (like `node_modules`), not from explicit patterns defined in your `.cgrignore` file.

## Merging CLI Excludes with File‑Based Rules

When you need temporary exclusions without editing the configuration file, pass `--exclude <pattern>` flags via the command line. These patterns merge with your `.cgrignore` rules using identical git‑wildmatch semantics, allowing ad‑hoc filtering during indexing operations.

```bash
cgr start --repo-path /path/to/monorepo --exclude "tmp/**"

```

This approach is useful for CI pipelines or one-off runs where you want to skip temporary directories without modifying the repository's ignore configuration.

## Default Exclusions and Override Behavior

Code‑Graph‑RAG automatically ignores common non‑source directories including `.git`, `node_modules`, `__pycache__`, `dist`, and `build`. You can override these defaults using negation patterns (e.g., `!node_modules`) in your `.cgrignore` when specific vendor directories must be indexed for dependency analysis.

## Internal Implementation and Performance

For large monorepos, pattern matching performance is critical. In [`codebase_rag/utils/path_utils.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/utils/path_utils.py), the system compiles ignore patterns once using `pathspec.PathSpec` with the `gitwildmatch` style, caching the result as `compiled_ignore_spec`. The function `should_skip_path` checks each file against this compiled specification during repository traversal, while `matches_ignore_patterns` provides a public API for path validation.

```python
from pathlib import Path
from codebase_rag.utils.path_utils import matches_ignore_patterns

repo_root = Path("/path/to/monorepo")
patterns = frozenset({"vendor/", "generated/", "*.gen.ts"})
rel_path = Path("src/module/file.gen.ts").as_posix()

if matches_ignore_patterns(rel_path, patterns):
    print("File will be ignored")
else:
    print("File will be indexed")

```

The complete rule set and advanced examples are documented in [`docs/advanced/ignore-patterns.md`](https://github.com/vitali87/code-graph-rag/blob/main/docs/advanced/ignore-patterns.md), and the test suite in [`codebase_rag/tests/test_cgrignore.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/tests/test_cgrignore.py) verifies correct handling of complex ignore and un‑ignore scenarios.

## Summary

- **Create a `.cgrignore`** file at your repository root using standard `.gitignore` syntax to configure permanent exclusions.
- **Use git‑wildmatch semantics**: bare names match anywhere, leading slashes anchor to root, `**` crosses directories, and trailing slashes target directories only.
- **Apply temporary filters** with the `--exclude` CLI flag without modifying your configuration file.
- **Override defaults** like `node_modules` or `build` using `!` negation patterns, though this only works for built‑in exclusions, not explicit `.cgrignore` rules.
- **Rely on compiled performance**: the engine uses `pathspec.PathSpec` cached in `compiled_ignore_spec` and checks paths via `should_skip_path` for efficient monorepo traversal.

## Frequently Asked Questions

### What is the exact syntax for `.cgrignore` patterns?

The `.cgrignore` file uses git‑wildmatch syntax identical to `.gitignore`. You can use `*` for single‑segment wildcards, `**` for recursive matching across directories, `?` for single characters, and `/` to anchor patterns to the repository root. Comments start with `#` and blank lines are ignored. See [`docs/advanced/ignore-patterns.md`](https://github.com/vitali87/code-graph-rag/blob/main/docs/advanced/ignore-patterns.md) for the complete specification.

### Can I rescue files from my own `.cgrignore` exclusions using negation?

No. Lines beginning with `!` only un‑ignore paths that match the built‑in default exclusions (such as `.git` or `node_modules`). They do not override explicit patterns you have defined in your `.cgrignore` file. To include those files, you must remove or modify the original exclusion rule.

### How does Code‑Graph‑RAG maintain performance when scanning millions of files?

The system compiles all ignore patterns into a `pathspec.PathSpec` object stored in `compiled_ignore_spec` within [`codebase_rag/utils/path_utils.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/utils/path_utils.py). This compiled specification is cached and reused, allowing the `should_skip_path` function to evaluate each file path against thousands of patterns in constant time during repository traversal.

### Can I combine multiple exclude sources for complex monorepo setups?

Yes. When you run the tool, patterns from the `.cgrignore` file are merged with any `--exclude` arguments passed via the CLI. Both sources use the same git‑wildmatch engine, so you can maintain a baseline configuration in the file while adding temporary project‑specific filters on the command line for different indexing profiles.