How the Understand Anything Plugin Handles Git Submodules

The Understand Anything plugin automatically detects Git submodules by parsing the .gitmodules file, recursively scans their contents to extract symbols and relationships, and merges these into the unified knowledge graph while resolving imports that cross submodule boundaries.

The Egonex-AI/Understand-Anything repository implements sophisticated submodule handling to ensure complete code analysis across repository boundaries. Understanding how the Understand Anything plugin handles git submodules requires examining the project walker, import resolution logic, and worktree detection mechanisms that treat nested dependencies as first-class project components.

Detecting Submodules via .gitmodules

The detection process begins in understand-anything-plugin/skills/understand/scan-project.mjs around line 462. The project walker checks for the presence of a .gitmodules file before commencing the file system traversal.

When detected, the parser reads each entry to enumerate submodule paths deterministically. This list feeds directly into the traversal queue, ensuring the walker enters submodule directories during the standard scan process.

Recursive Scanning and Graph Integration

Processing Submodule Files

Each submodule directory receives identical treatment to the parent repository. The plugin loads files, applies language-specific parsers, and extracts symbols, imports, and relationships before merging these nodes into the main project's knowledge graph.

Handling Nested Submodules

Because the walk implementation is recursive, submodules containing their own submodules are processed identically. The scanner detects nested .gitmodules files and descends into those paths, ensuring the generated graph reflects the complete hierarchical dependency structure without depth limitations.

Distinguishing Submodules from Worktrees

According to understand-anything-plugin/skills/understand/SKILL.md around line 52, the plugin differentiates between normal checkouts, submodules, and Git worktrees by comparing git rev-parse --git-dir and git rev-parse --git-common-dir. In a submodule, both commands resolve to the same path, while worktrees show divergent common directories.

This distinction ensures that output artifacts such as the .understand-anything/ folder are written to the correct repository root, preventing data corruption or misplaced analysis caches.

Resolving Cross-Submodule Imports

The understand-anything-plugin/skills/understand/extract-import-map.mjs file handles import resolution across submodule boundaries between lines 680-787 and 1239-1471. The extraction logic probes each import specifier as a potential submodule reference.

For each detected submodule, the system adds entries for language-specific package markers such as __init__.py in Python or mod statements in Rust. This creates accurate symbolic links between parent modules and their submodule dependencies, maintaining graph connectivity across repository boundaries.

Core Plugin Discovery

The understand-anything-plugin/packages/core/src/plugins/discovery.ts file registers files from submodule directories for analysis. This ensures the discovery phase treats submodule content identically to main repository files, making submodule symbols available for querying and relationship mapping.

Practical Implementation Examples

Trigger a scan on a repository containing submodules:

await runSkill('understand', {
  PROJECT_ROOT: '/path/to/your/main-repo',
  // Scanner automatically discovers submodules via .gitmodules
});

Verify that submodule files are included in the analysis:

git ls-files --recurse-submodules | grep -E '\.ts$'

Access a submodule's subgraph explicitly after scanning:

import { loadGraph } from '@understand-anything/core';
const subgraph = await loadGraph('/path/to/main-repo/.understand-anything/submodule-name');

Summary

  • Automatic detection: The plugin parses .gitmodules in scan-project.mjs to identify submodule paths before traversal begins
  • Recursive processing: Nested submodules are scanned to arbitrary depths using the same logic as the parent repository
  • Worktree differentiation: The plugin uses git rev-parse comparisons to distinguish submodules from worktrees as documented in SKILL.md
  • Import resolution: Cross-submodule imports resolve via extract-import-map.mjs to maintain graph connectivity
  • Unified discovery: Submodule files register through the core discovery system in discovery.ts for seamless analysis

Frequently Asked Questions

Does the Understand Anything plugin require manual configuration to scan submodules?

No manual configuration is required. The plugin automatically detects submodules by reading the .gitmodules file during the initial project walk in scan-project.mjs, then includes these paths in the standard traversal queue without requiring explicit inclusion lists.

How does the plugin handle nested submodules?

Nested submodules are processed recursively because the project walker in scan-project.mjs treats each discovered submodule as a standard directory tree. If a submodule contains its own .gitmodules file, the walker descends into those paths using the same detection logic applied to the parent repository.

Can the plugin distinguish between a submodule and a Git worktree?

Yes. As implemented in the logic referenced in SKILL.md, the plugin compares git rev-parse --git-dir against git rev-parse --git-common-dir. Matching paths indicate a submodule or main repository, while divergent paths indicate a worktree, ensuring artifacts are written to the correct location.

Does cross-submodule import resolution work for all supported languages?

The extract-import-map.mjs implementation handles cross-submodule imports across languages by probing import specifiers against submodule paths and adding entries for language-specific package markers like Python's __init__.py or Rust's mod statements, ensuring symbolic links are created regardless of the source language.

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 →