1<!--
2SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
3
4SPDX-License-Identifier: CC0-1.0
5-->
6
7# wt
8
9[](https://api.reuse.software/info/git.secluded.site/wt)
10[](https://liberapay.com/Amolith/)
11
12Git worktree manager using a bare repository pattern. Clone once, check
13out many.
14
15## tl;dr
16
17```
18wt c git@git.host:user/project.git # Clone into bare structure
19cd project/{canonical-branch}
20wt a feature/auth -b # Create worktree + branch
21cd ../feaTABTAB # Use cd + shell completions
22 # to navigate branches
23wt l # List worktrees
24wt r feature/auth -b # Remove worktree + branch
25```
26
27## Features
28
29- **Templated remote automation** — configure URL templates, select remotes on
30 clone, supports both contributing and own-project workflows
31- **Hooks** — copy files, create symlinks, run commands when adding worktrees
32- **Optional path styles** — nested (`feature/auth`) or flat (`feature_auth`)
33 worktree paths, schemes like `847-do-a-thing` work just fine too
34- **Bare repo structure** where `.bare/` holds the repository and worktrees live
35 as sibling directories
36- **Convert existing repos** — `wt init` migrates a normal clone to bare
37 structure
38
39## Installation
40
41Requires Lua 5.2 or later and
42[gum](https://github.com/charmbracelet/gum) for interactive prompts
43
44```
45curl -o ~/.local/bin/wt https://git.secluded.site/wt/blob/main/dist/wt?raw=1
46chmod +x ~/.local/bin/wt
47```
48
49## Usage
50
51### Commands
52
53| Command | Description |
54| --- | --- |
55| `wt c <url> [--remote name]... [--own]` | Clone into bare worktree structure |
56| `wt n <name> [--remote name]...` | Initialize fresh project |
57| `wt a <branch> [-b [<start-point>]]` | Add worktree, optionally create branch |
58| `wt r <branch> [-b] [-f]` | Remove worktree, optionally delete branch |
59| `wt l` | List worktrees with status |
60| `wt f` | Fetch all remotes |
61| `wt init [--dry-run] [-y]` | Convert existing repo to bare structure |
62
63### Clone workflows
64
65**Contributing to others' projects (default):**
66
67```
68wt c https://github.com/org/repo.git
69# origin → upstream, your remotes added from config
70```
71
72**Your own projects:**
73
74```
75wt c git@github.com:you/repo.git --own
76# First selected remote becomes origin
77# Additional remotes added from config
78```
79
80### Adding worktrees
81
82From inside an existing worktree, hooks from `.wt.lua` run automatically:
83
84```
85cd project/main
86wt a feature/new-thing -b # New branch from current HEAD
87wt a bugfix/issue-123 -b origin/main # New branch from specific start point
88wt a existing-branch # Checkout existing branch
89```
90
91## Configuration
92
93### Global config (`~/.config/wt/config.lua`)
94
95```lua
96return {
97 branch_path_style = "nested", -- or "flat"
98 flat_separator = "_", -- separator for flat style
99
100 remotes = {
101 github = "git@github.com:myuser/${project}.git",
102 gitlab = "git@gitlab.com:myuser/${project}.git",
103 },
104
105 default_remotes = "prompt", -- or {"github", "gitlab"}
106}
107```
108
109### Project config (`.wt.lua` in project root)
110
111```lua
112return {
113 hooks = {
114 copy = {".env.example", "Makefile.local"},
115 symlink = {".env", "node_modules"},
116 run = {"make setup", "npm install"},
117 }
118}
119```
120
121Hooks only run when `wt a` is executed from inside an existing worktree.
122You'll be prompted once per project to allow hooks; permissions are stored in
123`~/.local/share/wt/hook-dirs.lua`.
124
125## Contributions
126
127Patch requests are in
128[amolith/catchall](https://pr.pico.sh/r/amolith/catchall) on
129[pr.pico.sh](https://pr.pico.sh). You don't need a new account to
130contribute, you don't need to fork this repo, you don't need to fiddle
131with `git send-email`, you don't need to faff with your email client to
132get `git request-pull` working...
133
134You just need:
135
136- Git
137- SSH
138- An SSH key
139
140```
141# Clone this repo, make your changes, and commit them
142# Create a new patch request with
143git format-patch origin/main --stdout | ssh pr.pico.sh pr create amolith/catchall
144# After potential feedback, submit a revision to an existing patch request with
145git format-patch origin/main --stdout | ssh pr.pico.sh pr add {prID}
146# List patch requests
147ssh pr.pico.sh pr ls amolith/catchall
148```
149
150See "How do Patch Requests work?" on [pr.pico.sh](https://pr.pico.sh)'s home
151page for a more complete example workflow.
152
153---
154
155Some other tools if this one interested you
156
157- [agent-skills](https://git.secluded.site/agent-skills) - collection of Agent Skills for extending LLM capabilities
158- [garble](https://git.secluded.site/garble) - transform stdin with an LLM (fix typos, translate, reformat)
159- [formatted-commit](https://git.secluded.site/formatted-commit) - CLI that turns LLM input into well-formatted Conventional Commits