Fish shell utilities for managing git worktrees with this layout:
proj_dir/.bareis the central bare git repositoryproj_dir/mainis the main branch worktreeproj_dir/<branch>is a worktree for any additional branch
Example project path:
/base_path/project_name/.bare/base_path/project_name/main/base_path/project_name/feature-x
wt provides these subcommands:
wt co <branch>wt new <new-branch> [base-branch]wt convertwt updatewt statuswt prompt-pwdwt help [install]
Checks out an existing branch into proj_dir/<branch>.
Behavior:
- Uses a local branch if present.
- Falls back to a remote-tracking branch (
<remote>/<branch>) if needed. - Changes directory into the new worktree on success.
Creates a new branch and worktree at proj_dir/<new-branch>.
Behavior:
- Default base branch is
main. - Optional second argument sets a different base branch.
- Refuses to create if the new branch already exists (local or remote).
- Changes directory into the new worktree on success.
Examples:
wt new feature/login
wt new hotfix/api-v2 release/2026.02Converts a normal git checkout into this structure:
.gitbecomes.bare- Creates
mainworktree from current branch - Removes the original root working-tree files after
mainis created
Safety checks:
- Must run inside a normal git repo (with a
.gitdirectory) - Requires a clean working tree (no staged/unstaged/untracked files)
- Refuses detached HEAD
Runs update checks across all registered worktrees under proj_dir/.bare.
Behavior:
- Fetches all remotes first (
fetch --all --prune) - Only updates branches that have an upstream tracking branch
- Skips pull (with a note) if branch is ahead or diverged from upstream
- Notes branch/path mismatches when
relative_worktree_path != current_branch - Skips detached HEAD worktrees
Note:
fetch --all --pruneprunes stale remote-tracking refs, not local branches.- Pull is only attempted for branches that currently have an upstream.
Shows one-line status for each registered worktree in the project.
Behavior:
- Prints
mainfirst - Prints remaining worktrees by most recent commit time
- Includes branch/path mismatch note
- Includes upstream relation (
up-to-date,ahead,behind,diverged,no-upstream) - Includes dirty summary (
staged,unstaged,untracked)
Prints a fish-prompt-friendly path.
Behavior:
- Uses fish-style path shortening for normal directories
- If inside a wt project (
.barefound in parent path), keepsproj_dirname fully visible - Still shortens deeper subdirectories according to
fish_prompt_pwd_dir_length
Copy or symlink these files:
functions/wt.fish->~/.config/fish/functions/wt.fishcompletions/wt.fish->~/.config/fish/completions/wt.fish
Example using symlinks from this repo:
set -l repo (pwd)
ln -sf $repo/functions/wt.fish ~/.config/fish/functions/wt.fish
ln -sf $repo/completions/wt.fish ~/.config/fish/completions/wt.fishThen open a new fish session, or run:
source ~/.config/fish/functions/wt.fishFish completions are included for:
- subcommands (
co,new,convert,update,status,prompt-pwd,help) - branch names for
co - base branch suggestions for
newsecond argument wt help install
Branch completion reads from proj_dir/.bare when inside a converted project.
Add this to your ~/.config/fish/config.fish:
if not functions -q _wt_original_prompt_pwd
functions -c prompt_pwd _wt_original_prompt_pwd
end
function prompt_pwd
if type -q wt
set -l wt_pwd (wt prompt-pwd 2>/dev/null)
if test $status -eq 0 -a -n "$wt_pwd"
echo $wt_pwd
return
end
end
_wt_original_prompt_pwd
end