Skip to content

Latest commit

 

History

27 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
��
 
 
 
 
 

Repository files navigation

wt

Git worktree manager with GitHub integration. Shows CI status, PR review state, and cleans up merged worktrees automatically.

Features

  • Create worktrees from a bare repo with one command
  • List worktrees with last commit, PR number, CI pass/fail, and review status
  • Prune worktrees whose PRs have been merged
  • Multi-repo support via simple config files
  • VS Code workspace sync (optional) — auto-adds/removes worktrees

    Note: VS Code uses JSONC (JSON with comments/trailing commas) for workspace files. When wt modifies the file, it converts it to strict JSON — any comments in the file will be lost.

  • Shared files — symlink common untracked files into new worktrees (changes sync across all worktrees)
  • Zsh integration — cd wrapper and tab completion

Install

Homebrew

brew install francofrizzo/tap/wt

Manual

git clone https://github.com/francofrizzo/wt.git
ln -s "$PWD/wt/bin/wt" /usr/local/bin/wt

Requirements

  • macOS with zsh (target platform)
  • Bash 3.2+ (ships with macOS)

Dependencies

  • git
  • gh — GitHub CLI (for PR/CI status)
  • jq — JSON processor
  • perl — JSONC processing (ships with macOS)

Setup

The quickest way to get started — clone a GitHub repo:

wt init https://github.com/owner/myproject

This clones it as a bare repo, detects the GitHub slug and default branch, and writes the config. You're ready to create worktrees immediately.

Other ways to init

# Already inside a worktree or bare repo:
wt init

# Have an existing bare repo:
wt init myproject --bare ~/code/myproject.git

Optional flags

All three modes accept these optional flags:

Option Description Default
--worktrees Directory for worktrees <bare-parent>/<name>-worktrees
--repo GitHub owner/repo slug auto-detected from remote
--workspace VS Code .code-workspace file none
--shared Directory symlinked into new worktrees none
--default-branch Default branch name auto-detected from remote HEAD

Config format

Each repo is a sourceable shell file at ~/.config/wt/repos/<name>.conf:

BARE="/Users/you/code/myproject.git"
WORKTREES="/Users/you/code/myproject-worktrees"
REPO="owner/myproject"
DEFAULT_BRANCH="main"

Usage

Create a worktree

wt my-feature                    # new branch off origin/main
wt my-feature origin/dev         # new branch off origin/dev
wt my-feature HEAD               # new branch off the current branch
wt add my-feature                # explicit add subcommand
wt add my-feature --no-symlink   # copy shared files instead of symlinking

If the branch exists locally or on the remote, it checks it out. Otherwise, it creates a new branch from the base ref.

The worktree path is printed to stdout, so you can use it in scripts:

cd $(wt my-feature)

List worktrees

wt list

Output shows each worktree with:

  • Branch name and directory
  • Last commit (relative time + message)
  • PR number with CI status (pass/fail/running) and review state (approved/changes/pending)
  • Merged PRs shown dimmed

Jump to an existing worktree

wt cd my-feature

Fork current worktree

wt fork new-branch              # fork current branch into new-branch
wt fork new-branch --keep       # fork and keep changes in both worktrees
wt fork new-branch --no-symlink # copy shared files instead of symlinking

Creates a new worktree branching from the current one. If you have uncommitted changes (staged, unstaged, or untracked), they are moved to the new worktree automatically. Use --keep to preserve the changes in the original worktree as well.

Remove a worktree

wt rm my-feature
wt rm -f my-feature    # force remove (even if dirty)

Also cleans up the local branch if it has been fully merged.

Prune merged worktrees

wt prune               # interactive — prompts before removing
wt prune --dry-run     # preview what would be removed

Finds all worktrees whose PRs have been merged on GitHub (or have no unique commits vs the default branch) and removes them.

List configured repos

wt repos

Target a specific repo

wt --repo myproject list

By default, wt auto-detects the repo based on your current directory. The --repo flag is only needed when you're outside any configured worktree path.

Zsh integration

Add to your ~/.zshrc:

source "$(brew --prefix)/share/wt/wt.zsh"

This gives you:

  • Auto-cd: wt my-feature creates the worktree and cds into it
  • Tab completion: subcommands, branch names, worktree names, --repo names

How it works

wt operates on bare git repositories. Instead of cloning a repo normally, you clone it bare and create worktrees for each branch you work on. This lets you have multiple branches checked out simultaneously without stashing or switching.

Why bare repos? A normal clone has a single working tree tied to .git. Worktrees created from it share that .git directory, which can cause issues with IDE indexing, build caches, and lock files. A bare repo has no working tree of its own — every branch gets its own independent directory, cleanly isolated from each other.

~/code/
  myproject.git/              # bare repo (no working tree)
  myproject-worktrees/
    main/                     # worktree for main
    feature-auth/             # worktree for feature-auth
    fix-login-bug/            # worktree for fix-login-bug

Releasing a new version

Run the release script:

./release.sh 0.2.0

This tags the release, computes the tarball SHA, updates the Homebrew formula, and pushes everything. Users then run brew upgrade wt.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages