# How Worktrunk Manages Multiple Git Worktrees Efficiently: A Deep Dive into the Repository Architecture

> Discover how Worktrunk efficiently manages multiple Git worktrees using centralized caching, branch-first resolution, and atomic removal in its robust repository architecture. Learn the secrets to optimized Git workflows.

- Repository: [Maximilian Roos/worktrunk](https://github.com/max-sixty/worktrunk)
- Tags: deep-dive
- Published: 2026-09-14

---

**Worktrunk manages multiple Git worktrees efficiently by treating them as first-class resources with centralized caching, branch-first resolution, and atomic removal operations in [`src/git/repository/worktrees.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/git/repository/worktrees.rs).**

Worktrunk is a Rust-based CLI tool that streamlines Git worktree operations through a unified `Repository` abstraction. To manage multiple Git worktrees efficiently, the codebase implements a branch-first resolution model combined with aggressive caching in `RepoCache` and careful edge-case handling for submodules, symlinks, and prunable entries.

## Centralized Worktree Caching with `list_worktrees`

Worktrunk eliminates redundant Git invocations by maintaining a single source of truth for worktree state. The `Repository::list_worktrees` method executes `git worktree list --porcelain` once per operation cycle, parsing the porcelain output into `WorktreeInfo` structs and filtering out bare repository entries.

The implementation caches the result in `RepoCache`, ensuring subsequent callers receive a read-only slice (`&[WorktreeInfo]`) without re-invoking Git. This guarantees consistent views across all worktree queries while minimizing subprocess overhead.

According to the source code at [`src/git/repository/worktrees.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/git/repository/worktrees.rs) (lines 35-44), the cached list remains immutable for the duration of the command execution, preventing race conditions during concurrent operations.

## Branch-First Resolution Logic

Worktrunk resolves user-supplied selectors using a hierarchical priority system in `Repository::resolve_worktree` and `Repository::resolve_selector`. The algorithm first attempts branch name resolution via `worktree_for_branch`, then falls back to path lookup through `worktree_at_input_path`.

This branch-first approach means that a branch name uniquely identifies a worktree whenever possible, while still supporting detached HEAD worktrees or multiple check-outs via explicit paths. The resolution logic handles special selectors including `@` (current worktree), `-` (previous), and `^` (parent), with robust path normalization via `canonicalize` to handle symlinks and alternate root paths correctly.

The implementation at lines 98-124 of [`src/git/repository/worktrees.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/git/repository/worktrees.rs) enforces this resolution order consistently across all Worktrunk commands.

## Duplicate Branch Detection

When users force duplicate branch checkouts with `git worktree add --force`, Worktrunk detects the collision through `warn_duplicate_checkout`. This method scans the cached worktree list for branches present in multiple paths and emits a warning showing the first worktree that will be used, along with commands to remove duplicates.

Located at lines 136-156, this protection triggers once per process without imposing additional runtime cost on standard operations. The warning surfaces silent ambiguities that could otherwise cause operations to target unexpected worktrees.

## Robust Path Normalization

Path comparison reliability is critical for commands like `wt @` (current worktree). Worktrunk uses `canonicalize` combined with helper functions `resolve_input_path` and `paths_match` to compare worktree paths across symlinks and different spellings.

This normalization ensures that operations resolve correctly even on platforms with alternate root paths or case-insensitive filesystems. The path handling logic (lines 24-33) guarantees that relative inputs, absolute paths, and symbolic links all resolve to canonical representations before comparison.

## Prunable and Unusable Worktree Detection

Before operating on any worktree, Worktrunk verifies usability through `worktree_is_unusable`. This method performs two critical checks:

- Filesystem existence verification to detect deleted directories
- Git prunable status inspection to identify stale registrations

implemented at lines 48-56, this validation prevents TOCTOU (time-of-check-time-of-use) bugs by ensuring commands never operate on entries marked for pruning by Git, even if the filesystem path technically exists.

## Safe Removal and Race Condition Prevention

Worktrunk deliberately avoids `git worktree prune` because it indiscriminately deletes all stale entries. Instead, the `prune_worktree_entry` method targets specific paths using `git worktree remove <path>`, serialized through a repository-wide lock (`worktree_registry_write`) to prevent race conditions during concurrent removals.

The higher-level `remove_worktree` function (lines 86-104) handles submodule complexities by injecting `--force` when submodules are present, then rerunning cleanliness checks immediately before the destructive command. This two-phase verification guarantees safety while allowing automated cleanup of complex worktrees.

## Primary Worktree Abstractions

Functions `primary_worktree` and `home_path` centralize the notion of a "main" location, returning the repository root for standard repositories or the default-branch worktree for bare repos. These abstractions (lines 58-70) eliminate redundant path computations across commands that need to change to a sensible base directory.

The implementation handles both traditional and bare repository layouts transparently, ensuring scripts and interactive usage always have a reliable reference point.

## Summary

- **Cached Listings**: `list_worktrees` parses `git worktree list --porcelain` once into `RepoCache`, returning `&[WorktreeInfo]` for consistent, fast access.
- **Branch-First Resolution**: `resolve_worktree` checks branch names before paths, supporting `@`, `-`, and `^` selectors with canonical path matching.
- **Duplicate Protection**: `warn_duplicate_checkout` alerts users when `--force` creates ambiguous branch-to-worktree mappings.
- **Safety Checks**: `worktree_is_unusable` filters prunable entries and deleted paths before operations.
- **Atomic Removal**: `remove_worktree` uses path-specific pruning with `worktree_registry_write` locks, avoiding the destructive `git worktree prune` command.
- **Path Normalization**: `resolve_input_path` and `paths_match` handle symlinks and platform differences reliably.

## Frequently Asked Questions

### How does Worktrunk cache worktree information for performance?

Worktrunk calls `git worktree list --porcelain` exactly once per command execution through `Repository::list_worktrees`, storing parsed `WorktreeInfo` structs in `RepoCache`. Subsequent lookups receive a read-only slice (`&[WorktreeInfo]`), eliminating subprocess overhead and ensuring all operations see a consistent worktree state.

### What happens if the same branch exists in multiple worktrees?

When detecting duplicate branch checkouts (possible only with `git worktree add --force`), Worktrunk triggers `warn_duplicate_checkout` to display a warning showing which worktree will be used and how to remove duplicates. This prevents silent operation on the wrong directory without blocking execution.

### How does Worktrunk handle removal of worktrees containing submodules?

The `remove_worktree` function automatically detects submodules and injects the `--force` flag to Git, then performs final cleanliness checks immediately before deletion. This approach safely handles submodule complexity while avoiding the indiscriminate cleanup of `git worktree prune`, using repository-wide locks to prevent race conditions during concurrent removals.