Git Worktree Redirects in Understand-Anything: How Data Persistence Works Across Claude Code Sessions

Git worktree redirects in Understand-Anything automatically detect temporary Claude Code worktrees and redirect PROJECT_ROOT to the main repository root to prevent knowledge graph data loss.

The Understand-Anything project analyzes repositories and builds persistent knowledge graphs stored in .understand-anything/ directories. Because Claude Code creates temporary Git worktrees for sessions, the project implements a robust redirect mechanism to ensure these graphs survive session termination. This article explains the purpose, detection algorithm, and implementation of Git worktree redirects based on the Lum1104/Understand-Anything source code.

Why Git Worktree Redirects Are Necessary

When Claude Code executes skills, it often creates temporary Git worktrees—separate checkouts that share the same .git history but exist in isolated directories. If Understand-Anything wrote its knowledge graph to .understand-anything/ inside these ephemeral worktrees, the data would be deleted when the session ends and the worktree is removed.

To avoid losing incremental updates and generated metadata, the skill redirects PROJECT_ROOT from the temporary worktree back to the main repository root before any file operations occur. This ensures the .understand-anything/ directory always lives next to the permanent repository, preserving analysis across multiple Claude Code sessions.

How the Detection Mechanism Works

The redirect logic resides in Phase 0 – Pre‑flight of the skill configuration (skills/understand/SKILL.md). The mechanism uses two distinct Git commands to determine if the current environment is a worktree.

Detecting Worktree vs. Main Repository

The script compares paths returned by Git's plumbing commands:

COMMON_DIR=$(git -C "$PROJECT_ROOT" rev-parse --git-common-dir 2>/dev/null)
GIT_DIR=$(git -C "$PROJECT_ROOT" rev-parse --git-dir 2>/dev/null)
  • --git-common-dir returns the path to the shared .git directory that all worktrees reference (e.g., /path/to/project/.git).
  • --git-dir returns the worktree-specific path, which points to a file inside the common directory when in a worktree (e.g., /path/to/project/.git/worktrees/wt123).

When these paths differ, the code is executing inside a worktree. The parent directory of the common path (dirname "$COMMON_ABS") identifies the main repository root.

The Redirection Logic

After resolving absolute paths and comparing them, the script overwrites PROJECT_ROOT when a worktree is detected:

if [ -n "$COMMON_ABS" ] && [ "$COMMON_ABS" != "$GIT_ABS" ]; then
  MAIN_ROOT=$(dirname "$COMMON_ABS")
  if [ -d "$MAIN_ROOT" ] && [ "${UNDERSTAND_NO_WORKTREE_REDIRECT:-0}" != "1" ]; then
    echo "[understand] Detected git worktree at $PROJECT_ROOT"
    echo "[understand] Redirecting output to main repo root: $MAIN_ROOT"
    PROJECT_ROOT="$MAIN_ROOT"
  fi
fi

This redirection only occurs if the UNDERSTAND_NO_WORKTREE_REDIRECT environment variable is not set to 1, allowing users to opt out when they explicitly want to use worktree-local storage.

Implementation in the Skill Files

The complete detection and redirection snippet appears in skills/understand/SKILL.md (lines 46-66) and is mirrored in skills/understand-domain/SKILL.md for domain-specific analysis:

COMMON_DIR=$(git -C "$PROJECT_ROOT" rev-parse --git-common-dir 2>/dev/null)
GIT_DIR=$(git -C "$PROJECT_ROOT" rev-parse --git-dir 2>/dev/null)
if [ -n "$COMMON_DIR" ] && [ -n "$GIT_DIR" ]; then
  COMMON_ABS=$(cd "$PROJECT_ROOT" && cd "$COMMON_DIR" 2>/dev/null && pwd -P)
  GIT_ABS=$(cd "$PROJECT_ROOT" && cd "$GIT_DIR" 2>/dev/null && pwd -P)
  if [ -n "$COMMON_ABS" ] && [ "$COMMON_ABS" != "$GIT_ABS" ]; then
    MAIN_ROOT=$(dirname "$COMMON_ABS")
    if [ -d "$MAIN_ROOT" ] && [ "${UNDERSTAND_NO_WORKTREE_REDIRECT:-0}" != "1" ]; then
      echo "[understand] Detected git worktree at $PROJECT_ROOT"
      echo "[understand] Redirecting output to main repo root: $MAIN_ROOT"
      PROJECT_ROOT="$MAIN_ROOT"
    fi
  fi
fi

This Bash code resolves all paths to absolute form using pwd -P to avoid symlink issues, then conditionally redirects the project root before the skill begins its analysis phase.

Testing the Worktree Redirect Behavior

The project includes comprehensive tests in src/__tests__/worktree-redirect.test.mjs that validate the behavior across five scenarios:

  • Normal checkout: PROJECT_ROOT remains unchanged
  • Inside a worktree: Redirects to the main repository root
  • Inside a subdirectory of a worktree: Still redirects to the main repository root
  • With opt-out flag: Keeps the worktree path when UNDERSTAND_NO_WORKTREE_REDIRECT=1
  • Outside any Git repository: Path remains unchanged

The test suite ensures that the Bash logic correctly identifies worktrees regardless of the current working directory depth within the worktree structure.

Disabling the Redirect

For debugging or specific workflows where worktree-isolated storage is desired, disable the redirect by setting the environment variable before running the skill:

UNDERSTAND_NO_WORKTREE_REDIRECT=1 ua /understand

This bypasses the redirection logic and allows the knowledge graph to be written inside the temporary worktree, though the data will be lost when the worktree is cleaned up.

Summary

  • Git worktree redirects prevent data loss when Claude Code creates temporary worktrees by redirecting PROJECT_ROOT to the main repository root.
  • Detection relies on comparing --git-common-dir (shared .git location) with --git-dir (worktree-specific path)—differing paths indicate a worktree environment.
  • Implementation occurs in Phase 0 pre-flight within skills/understand/SKILL.md and skills/understand-domain/SKILL.md.
  • Testing is automated via src/__tests__/worktree-redirect.test.mjs, covering normal checkouts, worktrees, subdirectories, opt-outs, and non-repository contexts.
  • Disabling the feature is possible via the UNDERSTAND_NO_WORKTREE_REDIRECT environment variable.

Frequently Asked Questions

How does Understand-Anything detect if it is running in a Git worktree?

The skill runs git rev-parse --git-common-dir and git rev-parse --git-dir from the current PROJECT_ROOT. In a standard repository, these return the same path. In a worktree, --git-common-dir points to the main .git directory while --git-dir points to a worktree-specific subdirectory or file. When these paths differ, the code identifies the environment as a worktree and calculates the main repository root as the parent of the common directory.

What happens to my knowledge graph if I run Understand-Anything in a Claude Code worktree without the redirect?

Without the redirect, the .understand-anything/ directory would be created inside the temporary worktree directory. Since Claude Code removes these temporary worktrees when sessions end, your knowledge graph and any incremental analysis metadata would be permanently deleted. The redirect mechanism ensures the graph is written to the persistent main repository instead.

Can I use Understand-Anything with worktrees if I want separate graphs per worktree?

Yes, set the environment variable UNDERSTAND_NO_WORKTREE_REDIRECT=1 before executing the skill. This disables the redirection logic and allows the graph to be written relative to the worktree path. However, be aware that these graphs will be lost when the worktree is removed unless you manually copy the .understand-anything/ directory to a persistent location.

Where is the worktree redirect logic documented in the source code?

The primary implementation and documentation reside in skills/understand/SKILL.md within the Phase 0 pre-flight section. The same logic is duplicated in skills/understand-domain/SKILL.md for domain-specific skills. The automated test suite that validates this behavior is located at src/__tests__/worktree-redirect.test.mjs.

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 →