How to Configure .understandignore to Exclude Files from Analysis

The Understand-Anything project employs a two-step ignore system that merges hard-coded defaults with user-defined patterns in .understandignore files, using standard .gitignore syntax to filter files before they enter the knowledge-graph pipeline.

The Egonex-AI/Understand-Anything repository provides granular control over file analysis through a dedicated filtering mechanism. By configuring a .understandignore file, you can exclude build artifacts, dependency directories, and test fixtures from the scanning process. This configuration follows the exact pattern-matching rules implemented in the ignore npm package and integrates directly with the project scanner.

How the Ignore Filter System Works

The filtering logic is centralized in packages/core/src/ignore-filter.ts inside the createIgnoreFilter function. This function constructs an IgnoreFilter object by layering pattern sources in a specific order:

  1. Hard-coded defaults – Always excludes directories like node_modules/, extension patterns like *.lock, and minified files such as *.min.js via the DEFAULT_IGNORE_PATTERNS constant.
  2. Output directory file – Loads .understand-anything/.understandignore if present.
  3. Root configuration file – Loads .understandignore from the project root if present.

Later additions can override earlier patterns using negation rules. The combined filter exposes an isIgnored method that the scanner calls for every file enumerated via git ls-files or the fallback directory walk.

Where to Place Your Configuration Files

You can define exclusion rules in two locations relative to your project root:

Location File Path Loading Priority
Generated output .understand-anything/.understandignore Loaded second (can be overridden by root)
Project root .understandignore Loaded third (highest priority)

The scanner checks both paths during createIgnoreFilter execution. Patterns defined in the root file take precedence over those in the output directory, allowing you to fine-tune exclusions generated by automated tools.

Syntax and Pattern Capabilities

The .understandignore file uses identical syntax to .gitignore. The parser supports:

  • Directory patterns – Append a trailing slash to match only directories (dist/ ignores the folder but not a file named dist).
  • Glob wildcards – Use *.log to exclude all log files or temp/** for recursive matching.
  • Negation – Prefix with ! to re-include files (!dist/keep/important.js).
  • Comments – Lines starting with # are ignored by the parser.

This syntax is processed by the underlying ignore library, ensuring consistent behavior with version control exclusion rules.

Tracking User-Defined Exclusions

When you run the scan via skills/understand/scan-project.mjs, the CLI reports how many files were filtered specifically by your custom patterns versus the hard-coded defaults. Lines 71-93 implement this by constructing a defaults-only filter (using a temporary directory to guarantee no user ignore files are present) and comparing it against the combined filter:

const combined = createIgnoreFilter(projectRoot);
const userIgnoresPresent = hasUserIgnoreFile(projectRoot);
const defaultsOnly = userIgnoresPresent ? buildDefaultsOnlyFilter() : combined;

// Inside the file loop:
if (userIgnoresPresent && !defaultsOnly.isIgnored(rel)) {
  filteredByIgnore++;  // Increment only for user-provided exclusions
}

This filteredByIgnore metric helps you audit the impact of your configuration changes.

Generating a Starter Ignore File

Rather than writing patterns from scratch, you can leverage the generateStarterIgnoreFile function exported from packages/core/src/ignore-generator.ts. This utility:

  1. Parses your existing .gitignore for patterns not already covered by defaults.
  2. Detects common non-source directories like test/, docs/, and spec/.
  3. Outputs a commented template where every suggested pattern is prefixed with #.

Uncomment only the lines you need to activate exclusions. The generator is automatically invoked during the first scan if no .understand-anything/.understandignore exists (around line 220 of scan-project.mjs).

Practical Configuration Examples

Minimal Root Configuration

Create .understandignore at your project root with the following content to exclude common build artifacts while preserving specific files:


# Exclude build outputs

dist/
build/
out/

# Ignore test directories and logs

test/
*.log

# Re-include specific documentation from dist

!dist/keep/README.md

Programmatic Generation

Generate a starter file programmatically using the core package:

import { generateStarterIgnoreFile } from "./packages/core/src/ignore-generator.js";
import { writeFileSync } from "node:fs";
import { join } from "node:path";

const projectRoot = process.cwd();
const starter = generateStarterIgnoreFile(projectRoot);

writeFileSync(
  join(projectRoot, ".understand-anything", ".understandignore"),
  starter
);

This creates a commented template tailored to your repository structure.

Verifying Patterns in a REPL

Test your ignore logic before scanning:

import { createIgnoreFilter } from "./packages/core/dist/index.js";

const filter = createIgnoreFilter(process.cwd());

console.log(filter.isIgnored("node_modules/lodash/index.js")); // true (default)
console.log(filter.isIgnored("src/components/Button.tsx"));    // false
console.log(filter.isIgnored("debug.log"));                    // true if *.log is configured

Summary

  • Two valid locations exist for configuration: the project root (.understandignore) and the output directory (.understand-anything/.understandignore).
  • Loading order follows: hard-coded defaults → output directory file → root file, with later rules capable of negating earlier ones.
  • Standard syntax from .gitignore applies, including glob patterns, directory-specific matching with trailing slashes, and negation with !.
  • Implementation resides in packages/core/src/ignore-filter.ts, specifically the createIgnoreFilter function.
  • Metrics distinguish between default exclusions and user-defined filters via the filteredByIgnore counter in scan-project.mjs.
  • Starter templates can be auto-generated via generateStarterIgnoreFile in packages/core/src/ignore-generator.ts.

Frequently Asked Questions

Does .understandignore use the exact same syntax as .gitignore?

Yes. The system delegates pattern parsing to the standard ignore library, which implements the Git ignore specification. This includes support for globbing, character classes, negation with !, and comments. Trailing slashes specifically denote directory matching, just like in Git.

Can I override a specific file that is excluded by default?

Yes. While the hard-coded defaults in DEFAULT_IGNORE_PATTERNS exclude files like those in node_modules/, you can re-include specific paths using negation patterns in your .understandignore. Place the negation rule after the exclusion rule (or rely on the loading order where root patterns process last) to force inclusion of critical files.

Why does the scanner report "filtered by ignore" separately from the total file count?

The CLI distinguishes between files excluded by built-in defaults (like node_modules/) and files excluded by your custom .understandignore patterns. By comparing the combined filter against a defaults-only baseline, the scanner increments filteredByIgnore only for matches caused by your specific configuration. This helps you verify that your exclusions are working as intended without noise from standard ignores.

What happens if I have both .understandignore files present?

Both files are loaded and merged. The scanner first applies hard-coded defaults, then reads .understand-anything/.understandignore, and finally reads .understandignore from the project root. Because patterns are additive, definitions in the root file can override those in the output directory using negation syntax, giving you final control over the filter behavior.

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 →