How to Exclude Specific Files or Patterns from Dead Code Analysis in Code-Graph-RAG

Use the --exclude flag with glob patterns when running cgr dead-code to filter out generated, vendored, or test files from the reachability analysis.

The cgr dead-code command in the vitali87/code-graph-rag repository identifies unreachable functions and methods by walking a call graph built from your source tree. When generated protobuf stubs, vendored dependencies, or auto-generated client code appear in the dead code report, you can suppress them using path-based glob exclusions that filter symbols after the reachability walk completes.

How the Exclusion Filter Works

The exclusion mechanism operates at two distinct layers to ensure matching symbols never appear in the final dead code list.

CLI Layer: The --exclude Flag

When invoking cgr dead-code from the terminal, pass the --exclude flag multiple times to supply one or more glob patterns. Each pattern is matched against the repo-relative file path of symbols (for example, src/client/core/api.py).

According to the source code in codebase_rag/cli.py, these patterns are collected and passed to default_dead_code_config(..., exclude_patterns=tuple(...)), which instantiates a DeadCodeConfig dataclass. This configuration object stores the exclusion patterns in its exclude_patterns field (codebase_rag/dead_code.py:44-52).

Engine Layer: Filtering in dead_code_from_graph

After the reachability walk identifies candidate dead symbols, the dead_code_from_graph function applies the exclusion filter. The implementation in codebase_rag/dead_code.py:792-800 uses fnmatch to test each symbol's file path against the configured patterns:

if config.exclude_patterns:
    dead = {
        qn
        for qn in dead
        if not any(
            fnmatch(str(props_by_qn[qn].get(cs.KEY_PATH) or ""), pattern)
            for pattern in config.exclude_patterns
        )
    }

This logic discards any symbol whose repo-relative path matches at least one exclusion glob, ensuring the final report contains only relevant dead code.

Writing Effective Glob Patterns

To avoid accidentally excluding production code or failing to match target files, follow these pattern-writing guidelines:

  • Quote the glob to prevent shell expansion before cgr receives the argument.
  • Match the full path because patterns are tested against the complete repo-relative path. Use 'tests/*' or 'src/tests/*' rather than just 'tests'.
  • Place wildcards around directories since * spans directory separators. The pattern '*/tests/*' captures nested test directories without matching production paths like contests/entry.py.
  • Be specific with your globs; broad patterns like '*tests*' risk excluding legitimate files such as contests/entry.py if they appear in non-test directories.

Practical Examples

Exclude generated client code and files containing .gen. in the name:

cgr dead-code \
  --exclude '*client/core*' \
  --exclude '*.gen.*'

Exclude a specific auto-generated protobuf stub file:

cgr dead-code --exclude 'src/protos/generated_pb2.py'

Combine exclusions with CI-friendly JSON output and failure flags:

cgr dead-code \
  --format json \
  --output dead-code.json \
  --fail-on-found \
  --exclude '*_generated*'

For programmatic usage, build a DeadCodeConfig directly in Python:

from codebase_rag.dead_code import default_dead_code_config, dead_code_from_graph

# Configure exclusions for vendor directories and generated files

config = default_dead_code_config(
    include_tests=True,
    include_classes=False,
    exclude_patterns=('*vendor/*', '*_generated.py')
)

# Analyze the graph (nodes and rels loaded previously)

dead_qns = dead_code_from_graph(nodes, rels, prefix, config)

Summary

  • The cgr dead-code command supports file exclusion via the --exclude flag using standard glob syntax.
  • Exclusion patterns are stored in the exclude_patterns field of the DeadCodeConfig class defined in codebase_rag/dead_code.py.
  • Filtering occurs after the reachability analysis in dead_code_from_graph, removing matches from the final dead symbol set.
  • Patterns must match the full repo-relative file path; use wildcards like */tests/* to target specific directory structures.
  • Always quote glob patterns in shell commands to prevent premature expansion.

Frequently Asked Questions

Can I use multiple --exclude flags in a single command?

Yes. The CLI accepts multiple --exclude arguments, which are collected into a tuple and passed to the configuration. For example: cgr dead-code --exclude '*tests/*' --exclude '*vendor/*'.

Do exclusion patterns support regular expressions?

No. The engine uses Python's fnmatch module, which supports Unix shell-style wildcards (*, ?, [seq]), not full regular expressions. Patterns are matched against the repo-relative file path strings.

When in the analysis process are exclusions applied?

Exclusions are applied after the reachability walk completes but before the final report is generated. This means excluded files are still parsed and included in the call graph; they are simply filtered from the dead code output. This ensures that calls from excluded files to production code are still considered during reachability analysis.

How do I exclude an entire directory like node_modules or vendor?

Use a glob pattern that matches the directory contents, such as '*vendor/*' or */node_modules/*'. Remember that the pattern must match the full repo-relative path, so including wildcards on both sides of the directory name ensures you capture files at any nesting level within that directory.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →