# How Worktrunk Makes Git Worktrees Addressable Like Branches: Branch-First Resolution Explained

> Discover how Worktrunk enables branch-first resolution for Git worktrees, making them as addressable as branches. Learn about its unique one-to-one mapping strategy.

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

---

**Worktrunk makes Git worktrees as addressable as branches by implementing a branch-first canonical resolution strategy in `Repository::resolve_worktree`, which attempts to match user input as a branch name before falling back to a path alias, while enforcing a strict one-to-one mapping between worktrees and branches.**

Git worktrees are traditionally accessed by filesystem paths, while branches are referenced by names. In the `max-sixty/worktrunk` repository, this distinction collapses through a canonical resolution layer that treats worktrees as first-class entities addressable by their associated branch names. This architectural decision eliminates the friction of juggling path-based references when switching development contexts.

## The Branch-First Resolution Strategy

### Canonical Resolution via `Repository::resolve_worktree`

At the heart of Worktrunk's addressability model lies the `resolve_worktree` method implemented in [`src/git/repository/worktrees.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/git/repository/worktrees.rs). This function interprets any user-supplied identifier through a **branch-first** lens. When you invoke a command with a worktree argument, the resolver first queries the repository's branch registry to determine if the input matches an existing branch name. If a match exists, Worktrunk returns the worktree currently associated with that branch. Only when no branch matches does the resolver treat the input as a **filesystem path alias**, allowing direct references to worktree directories created via standard `git worktree add` operations.

This dual-resolution strategy enables seamless workflows where `wt switch feature-branch` works identically whether the branch sits in the main working tree or an auxiliary worktree directory.

### Unified Command Interface

Because the canonicaliser abstracts away the underlying storage location, the CLI exposed in [`src/cli/mod.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/cli/mod.rs) accepts branch names and paths interchangeably. You do not need separate flags to distinguish between "switch to a branch" and "switch to a worktree." The resolution logic handles both cases transparently, reducing cognitive load and command complexity.

## Enforcing Strict Worktree-to-Branch Mappings

Worktrunk enforces that each worktree maps to **exactly one branch** and never allows retargeting. This immutability guarantee resides in the worktree registry maintained within [`src/git/repository/worktrees.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/git/repository/worktrees.rs). When you request a branch that lacks an associated worktree, Worktrunk creates a new worktree via [`src/git_wt.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/git_wt.rs) rather than repointing an existing one.

This design prevents accidental data loss. If a worktree needs to track a different branch, Worktrunk explicitly removes the old mapping and creates a fresh worktree, mirroring Git's native safety semantics but adding the convenience of branch-based addressing.

## Core Implementation Files

The addressability system spans several Rust modules:

- **[`src/git/repository/worktrees.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/git/repository/worktrees.rs)** – Implements the `resolve_worktree` method, maintains the worktree-to-branch registry, and provides creation and deletion helpers.
- **[`src/git_wt.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/git_wt.rs)** – Contains high-level wrappers around Git worktree commands; all operations route through the canonical resolver.
- **[`src/git/repository/branches.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/git/repository/branches.rs)** – Supplies branch lookup utilities consumed by the resolution logic.
- **[`src/cli/mod.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/cli/mod.rs)** – Defines command-line arguments where worktree parameters are documented as accepting "branch name or path".
- **[`src/git/repository/mod.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/git/repository/mod.rs)** – Exposes the public `Repository` API including the `resolve_worktree` entry point.

## Practical Usage Examples

The following patterns demonstrate how branch-first resolution simplifies daily workflows:

Switch to a branch by name, regardless of which worktree holds it:

```rust
// Rust API usage
let repo = Repository::open(".")?;
let handle = repo.resolve_worktree("feature-xyz")?; // Branch-first lookup
wt::switch(&handle)?;

```

Command-line equivalent:

```bash

# Switches to the worktree holding feature-xyz, or creates one

wt switch feature-xyz

```

Explicitly reference a worktree by its filesystem path when needed:

```rust
// Path alias fallback
let handle = repo.resolve_worktree("./temp-hotfix")?;

```

```bash

# Uses the worktree at ./temp-hotfix directly

wt switch ./temp-hotfix

```

## Summary

- **Worktrunk** unifies branch and worktree addressing through a central `Repository::resolve_worktree` canonicaliser located in [`src/git/repository/worktrees.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/git/repository/worktrees.rs).
- The resolver applies a **branch-first** strategy, checking branch names before treating input as path aliases.
- A strict **one-to-one mapping** between worktrees and branches prevents retargeting and ensures data safety.
- All CLI commands in [`src/cli/mod.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/cli/mod.rs) benefit from transparent resolution, accepting branch names or paths interchangeably.
- The [`src/git_wt.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/git_wt.rs) module handles worktree lifecycle operations while respecting the canonical addressing scheme.

## Frequently Asked Questions

### What is the difference between a branch name and a path alias in Worktrunk?

In Worktrunk's resolution logic, a **branch name** takes precedence. When you supply an argument to commands like `wt switch`, the system first queries [`src/git/repository/branches.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/git/repository/branches.rs) to locate a matching branch. If found, Worktrunk uses the worktree associated with that branch. A **path alias** acts as a fallback mechanism; if no branch matches, the input is interpreted as a filesystem path to an existing worktree directory.

### How does Worktrunk handle switching to a branch already checked out in another worktree?

Worktrunk detects existing associations through the worktree registry in [`src/git/repository/worktrees.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/git/repository/worktrees.rs). If the target branch already resides in a worktree, `resolve_worktree` returns a handle to that existing worktree, and the CLI switches to it. If the branch is not currently checked out anywhere, Worktrunk creates a new worktree via [`src/git_wt.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/git_wt.rs) and checks the branch out there.

### Why does Worktrunk enforce a one-to-one mapping between worktrees and branches?

This constraint prevents ambiguous states where a single worktree might silently jump between branches. By disallowing retargeting, Worktrunk ensures that `repo.resolve_worktree("main")` always returns the same filesystem location unless explicitly recreated. This immutability simplifies debugging and prevents accidental loss of uncommitted changes that could occur if a worktree were repointed underneath an active session.

### Can I use an existing Git worktree with Worktrunk?

Yes. Worktrunk's path alias resolution recognizes worktrees created via standard `git worktree add` commands. When you reference such a directory, the resolver in [`src/git/repository/worktrees.rs`](https://github.com/max-sixty/worktrunk/blob/main/src/git/repository/worktrees.rs) registers the mapping between the checked-out branch and the provided path, integrating the existing worktree into Worktrunk's branch-first addressing system.