Skip to content

Repository files navigation

Git Worktree Alias

Ticket-based worktree lifecycle for git: open, see, close.

One command per phase of the work. git wt 101 creates or resumes an isolated workspace for ticket WTA-101, bare git wt shows every worktree with its divergence and dirt, and git wt close 101 shows the evidence (unmerged commits, dirty files) before it merges, removes, or refuses. Integrates with the MDT (Markdown Ticket) system for automatic project code resolution.

Features

  • Lifecycle commands - git wt (dashboard), git wt open (create/resume), git wt close (merge-aware removal), git wt path (cd handoff)
  • Dashboard - bare git wt lists worktrees with branch, ahead/behind vs base, dirty count, and age
  • Idempotent open - existing worktree resumes with a cd hint (exit 0); a branch without a worktree gets one attached
  • Evidence-first close (WTA-003) - unmerged commits trigger a merge prompt before anything is destroyed; --merge, --merge-to <branch>, --delete-unmerged, --quiet, and worktree.wt.autoMerge for automation
  • Environment bootstrap - optional worktree.wt.syncFiles (copy e.g. .dev.vars) and worktree.wt.setupCmd (run e.g. bun install) on open
  • Smart project code detection - reads the project code from .mdt-config.toml
  • Configurable ticket prefix and zero-padding - GitHub, JIRA, or custom formats
  • Flexible path templates - {worktree_name} and {project_dir} placeholders, relative or absolute

Quick Start

Prerequisites

  • Git 2.48+ (for git worktree add --relative-paths)
  • Bash or Zsh shell

Installation

# Download, install the git-wt script to ~/.git-wt/, and register the aliases
curl -fsSL https://raw.githubusercontent.com/rikby/mdt-git-worktree-alias/main/install_aliases.sh | bash

The installer writes one implementation script to ~/.git-wt/git-wt and registers two thin aliases, git wt and git wt-rm. Re-running the installer upgrades in place.

Basic Usage

git wt 101        # open (create or resume) WTA-101
git wt            # dashboard: every worktree, divergence, dirt, age
git wt close 101  # evidence-first close with merge protection

No configuration is required: with nothing configured, worktrees are created outside the repository at ../.git-worktrees/{project_dir}-{worktree_name} (the first run offers to remember it in your global config). To choose a different location:

git config --global worktree.wt.defaultPath ".gitWT/{worktree_name}"        # inside the repo
git config --global worktree.wt.defaultPath "~/worktrees/{worktree_name}"   # elsewhere, outside

Usage

Opening worktrees

git wt 101            # open WTA-101 (reads project code from .mdt-config.toml)
git wt open WTA-101   # explicit subcommand form
git wt MDT-205        # full ticket name

# Running the same command again resumes instead of failing:
git wt 101
# ✓ worktree exists: /worktrees/my-repo-WTA-101
#   branch: WTA-101
#   dirty files: 0
# → cd /worktrees/my-repo-WTA-101

A branch that exists without a worktree is resumed too: git wt attaches a worktree to it instead of erroring.

The dashboard

git wt          # or: git wt list
# WORKTREE                   BRANCH                      VS main    DIRTY  AGE
# * my-repo                  main                        (base)     0      2d
#   my-repo-WTA-101          WTA-101                     ↓5 ↑1      0      3h
#   my-repo-gpde-017         gpde-017-teaching-move      ↓2 ↑0      17     3d

↓N marks commits the base branch is ahead (stale fork — merge or rebase soon); ↑N marks unmerged work. * marks your current worktree. Stale registrations are pruned automatically.

Closing worktrees

git wt close 101       # or the legacy alias: git wt-rm 101

Close evaluates before it destroys. For a branch with unmerged commits you get the evidence and one question:

Found worktree: /worktrees/my-repo-WTA-101
Branch: WTA-101
  unmerged commits: 3 (not in main)
Merge branch "WTA-101" into "main" before closing? [y/N]
  • y — merges into the current branch, removes the worktree, deletes the branch (safe git branch -d)
  • N — cancels; worktree and branch are preserved untouched

A fully merged branch asks one confirmation (Remove worktree and branch? [y/N]) and closes in one step.

Non-interactive variants:

git wt close --merge 101              # merge into current branch, no prompt
git wt close --merge-to main 101      # merge into a specific branch, switch back
git wt close --delete-unmerged 101    # discard unmerged work (git branch -D)
git wt close --quiet 101              # no prompts; fails if merge needed but not enabled
git wt close --force 101              # remove despite uncommitted changes

git config worktree.wt.autoMerge true # always merge when unmerged commits exist

Exit codes: 0 ok or cancelled · 1 general error · 2 merge conflict (state preserved for manual resolution) · 3 conflicting flags.

Getting the path (cd handoff)

git wt path 101        # prints just the absolute path
cd "$(git wt path 101)"

# or a shell wrapper:
wt() { cd "$(git wt path "$1")"; }

Configuring Paths

The default (../.git-worktrees/{project_dir}-{worktree_name}) keeps worktrees outside the repo — no .gitignore entry needed — and prefixes the repo folder name so multiple repos don't collide.

# Keep the default, or switch to:

# Inside repository (requires .gitWT/ in .gitignore)
git config --global worktree.wt.defaultPath ".gitWT/{worktree_name}"

# Outside repository (absolute path)
git config --global worktree.wt.defaultPath "~/worktrees/{worktree_name}"

# Include project directory name
git config --global worktree.wt.defaultPath "/worktrees/{project_dir}-{worktree_name}"

Environment bootstrap (optional)

# Files copied from the repo you run `git wt` in (if missing in the new worktree)
git config worktree.wt.syncFiles ".dev.vars .env.local"

# Command run inside the freshly created worktree
git config worktree.wt.setupCmd "bun install"

Git never propagates untracked or ignored files into a new worktree — this setting does it for the files you name.

Fork base (optional)

# Always fork new worktrees from a specific branch (default: current HEAD)
git config worktree.wt.baseBranch main

When the base is behind its upstream, git wt open prints a non-blocking notice suggesting a pull.

Testing

bats test/

Example output:

137 tests, 0 failures

Configuration Reference

Key Purpose Default
worktree.wt.defaultPath Path template ({worktree_name}, {project_dir}) ../.git-worktrees/{project_dir}-{worktree_name}
worktree.wt.prefix Prefix for numeric tickets (with .mdt-config.toml fallback) —
worktree.wt.zeroPadDigits Zero-padding width for ticket numbers 3 for MDT projects
worktree.wt.autoMerge true/on/yes/1 — auto-merge on close false
worktree.wt.baseBranch Branch to fork new worktrees from current HEAD
worktree.wt.syncFiles Files copied into new worktrees if missing —
worktree.wt.setupCmd Command run inside a new worktree —

Legacy worktree.defaultPath (without .wt) still works via fallback; the new namespace wins.

Input Type Detection

# Already prefixed - passes through unchanged
git wt PROJ-123    # Creates PROJ-123

# Pure numeric - applies prefix and zero-padding
git wt 42          # Creates ABC-042 (with prefix="ABC-", zeroPadDigits=3)

# Text input - passes through unchanged (prefix ignored)
git wt feature-login  # Creates feature-login

Resources

License

MIT License

About

Git worktree aliases for ticket-based development that automate creating and removing isolated workspaces using simple commands like git wt 101.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages