wt uses TOML configuration files with hierarchical overrides.
# Create global config with documented defaults
wtconfig init --global
# Create repo-specific config
wtconfig init
# View effective configuration with sources
wtconfig showConfiguration is merged from multiple sources (highest priority first):
runtime flag > .wt.toml (repo) > ~/.config/wt/config.toml (global) > defaults
| Source | Location | Scope |
|---|---|---|
| Runtime flag | --timeout, --remote |
Single command |
| Repo config | .wt.toml in project root |
Single repository |
| Global config | ~/.config/wt/config.toml |
All repositories |
| Defaults | Built into wt | Fallback |
| Location | Description |
|---|---|
$XDG_CONFIG_HOME/wt/config.toml |
Global config (XDG) |
~/.config/wt/config.toml |
Global config (fallback) |
.wt.toml |
Repo-specific config |
| Option | Type | Default | Description |
|---|---|---|---|
worktree_root |
string | (none) | Directory where projects are cloned |
default_owner |
string | (none) | Default owner/org for shorthand clone |
default_remote |
string | origin |
Remote for fetch/push/prune operations |
default_base_branch |
string | (none) | Base branch for new worktrees |
branch_template |
string | (none) | Template for generated branch names |
auto_track |
bool | false |
Auto-track remote branches without prompting |
| Option | Type | Default | Description |
|---|---|---|---|
git_timeout |
int | 120 |
Default git operation timeout (seconds) |
git_long_timeout |
int | 600 |
Clone/fetch timeout (seconds) |
hook_timeout |
int | 30 |
Hook command timeout (seconds) |
| Option | Type | Default | Description |
|---|---|---|---|
hooks.post_clone |
[]string | [] |
Commands to run after clone |
hooks.post_add |
[]string | [] |
Commands to run after add/new |
# ~/.config/wt/config.toml
# Where to clone repositories (optional)
# If not set, clones to current directory
worktree_root = "~/DEV/worktrees"
# Default owner/org for shorthand clone
# Allows: wt clone repo -> wt clone myorg/repo
default_owner = "myorg"
# Remote configuration
default_remote = "origin"
default_base_branch = "main"
# Branch naming template (for --issue/--pr)
# Available: {{type}}, {{number}}, {{slug}}
branch_template = "{{type}}/{{number}}-{{slug}}"
# Timeouts (seconds)
git_timeout = 120 # Default operations
git_long_timeout = 600 # Clone/fetch
hook_timeout = 30 # Each hook command
[hooks]
# Run after 'wtclone'
# Named hooks (resolved from hooks directory) or inline commands
post_clone = [
"gh-default", # Bundled hook: auto-configure gh CLI
"zoxide add $WT_PATH", # Inline command
]
# Run after 'wtadd/new'
post_add = [
"direnv", # Bundled hook: auto-allow .envrc
"zoxide add $WT_PATH",
"cp $WT_PROJECT_ROOT/$WT_DEFAULT_BRANCH/.envrc $WT_PATH/ 2>/dev/null || true",
]wt provides workflow presets that combine branch naming conventions with hook execution.
| Workflow | Flag | Branch Template | Description |
|---|---|---|---|
feature |
--feature, -f |
feat/{slug} |
New feature work |
bugfix |
--bugfix, -b |
fix/{slug} |
Bug fixes |
pr-review |
--pr-review |
{branch} |
PR review (uses PR's actual branch) |
branch |
(default) | {name} |
Plain branch |
Each workflow can define hooks that run at different stages:
| Hook Stage | When it runs | Purpose |
|---|---|---|
pre_create |
Before worktree creation | Fetch metadata, suggest branch |
post_add |
After worktree is created | Setup environment |
Pre-create hooks can communicate back to wt using the hook helper protocol.
Override or extend workflows in your config:
[workflows.feature]
description = "New feature development"
branch_template = "feat/{slug}"
[workflows.feature.hooks]
pre_create = ["github-issue"] # Fetch issue metadata for --issue flag
post_add = ["direnv", "zoxide"]
[workflows.bugfix]
description = "Bug fix"
branch_template = "fix/{slug}"
[workflows.bugfix.hooks]
pre_create = ["github-issue"]
post_add = ["direnv", "zoxide"]
[workflows.pr-review]
description = "Review a pull request"
branch_template = "{branch}"
[workflows.pr-review.hooks]
pre_create = ["github-pr"] # Fetches PR's actual branch
post_add = ["direnv", "zoxide"]
# Custom workflow
[workflows.hotfix]
description = "Emergency hotfix"
branch_template = "hotfix/{slug}"
[workflows.hotfix.hooks]
pre_create = ["github-issue"]
post_add = ["direnv", "zoxide"]# Use built-in workflows
wtadd --feature auth
wtadd --bugfix --issue 42
wtadd --pr-review 123
# Use custom workflow
wtadd --workflow hotfix security-patchCreate .wt.toml in your project root to override global settings:
# .wt.toml (in project root)
# This repo uses 'upstream' instead of 'origin'
default_remote = "upstream"
# Use 'develop' as base for new branches
default_base_branch = "develop"
# Longer timeout for this large repo
git_long_timeout = 900
[hooks]
# Project-specific hooks
post_add = [
"npm install",
"cp .env.example .env",
]Hooks have access to these environment variables:
| Variable | Description | Example |
|---|---|---|
WT_PATH |
Path to the new worktree | /home/user/DEV/worktrees/repo/main |
WT_BRANCH |
Branch name | feature/auth |
WT_PROJECT_ROOT |
Project root (contains .bare/) |
/home/user/DEV/worktrees/repo |
WT_DEFAULT_BRANCH |
Default branch name | main |
WT_WORKFLOW |
Current workflow name | feature, bugfix, pr-review |
WT_WORKFLOW_PREFIX |
Branch prefix from workflow | feat, fix |
WT_ISSUE |
GitHub issue number (if passed) | 42 |
WT_PR |
GitHub PR number (if passed) | 123 |
WT_OUTPUT |
Output file for hook protocol | (internal path) |
WT_LIB |
Directory containing helpers.sh | (internal path) |
Hook commands support Go template variables:
| Template | Equivalent Variable |
|---|---|
{{.Path}} |
$WT_PATH |
{{.Branch}} |
$WT_BRANCH |
{{.ProjectRoot}} |
$WT_PROJECT_ROOT |
{{.DefaultBranch}} |
$WT_DEFAULT_BRANCH |
Example:
[hooks]
post_add = [
"echo 'Created {{.Branch}} at {{.Path}}'",
]Note: Template values are automatically shell-quoted for security.
- Hooks run in the order listed
- Each hook runs with the worktree path as working directory
- A failing hook logs a warning but doesn't block subsequent hooks
- Each hook command has a configurable timeout (default 30 seconds)
- Hooks that exceed the timeout are terminated
# Show effective configuration with sources
wtconfig showOutput displays settings, hooks, and workflows in formatted tables showing the key, value, and source file for each setting.
Override any timeout via command flags:
# Override git timeout for slow networks
wtclone owner/repo --timeout 900
# Override hook timeout
wtadd feature/auth --hook-timeout 60See Hooks Examples for more hook recipes.
wt supports both named hooks (scripts) and inline commands.
[hooks]
# Named hook - resolved from custom/ or community/ directory
post_clone = ["gh-default"]
# Inline command - executed as shell command
post_add = ["direnv allow", "echo done"]
# Mix both
post_add = ["gh-default", "zoxide add $WT_PATH"]| Directory | Purpose |
|---|---|
~/.config/wt/hooks/custom/ |
Your custom hooks |
~/.config/wt/hooks/community/ |
Bundled/shared hooks |
Custom hooks take precedence over community hooks with the same name.
wtconfig init --globalThis installs bundled hooks to the community directory:
gh-default.sh- Auto-configure GitHub CLI default repodirenv.sh- Auto-allow .envrc fileszoxide.sh- Register worktrees with zoxidegithub-issue.sh- Fetch GitHub issue metadata (pre_create hook)github-pr.sh- Fetch GitHub PR metadata and branch (pre_create hook)
See Hooks Examples for the full hooks ecosystem documentation.
When running wtadd <branch>, wt checks if the branch already exists on any remote.
Behavior:
- If found on one remote: prompts to track or create new (unless
auto_track = true) - If found on multiple remotes: errors with list, requires
--remoteflag - If not found: creates new local branch
Flags:
| Flag | Description |
|---|---|
--track |
Track the remote branch (required in scripts when remote exists) |
--new |
Force create new local branch even if remote exists |
--fetch |
Fetch all remotes before checking for branches |
--remote |
Specify which remote to use when branch exists on multiple |
Config:
# Auto-track remote branches without prompting (like git checkout)
auto_track = falseWhen auto_track = true, wt automatically tracks the remote branch without prompting in interactive mode. In JSON/script mode, --track is still required for explicit intent.