README.md

  1<!--
  2SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
  3
  4SPDX-License-Identifier: CC0-1.0
  5-->
  6
  7# wt
  8
  9[![REUSE status](https://api.reuse.software/badge/git.secluded.site/wt)](https://api.reuse.software/info/git.secluded.site/wt)
 10[![Donate using Liberapay](https://img.shields.io/liberapay/receives/Amolith.svg?logo=liberapay)](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.
 42
 43```
 44curl -o ~/.local/bin/wt https://git.secluded.site/wt/blob/main/src/main.lua?raw=1
 45chmod +x ~/.local/bin/wt
 46```
 47
 48## Usage
 49
 50### Commands
 51
 52| Command | Description |
 53| --- | --- |
 54| `wt c <url> [--remote name]... [--own]` | Clone into bare worktree structure |
 55| `wt n <name> [--remote name]...` | Initialize fresh project |
 56| `wt a <branch> [-b [<start-point>]]` | Add worktree, optionally create branch |
 57| `wt r <branch> [-b] [-f]` | Remove worktree, optionally delete branch |
 58| `wt l` | List worktrees with status |
 59| `wt f` | Fetch all remotes |
 60| `wt init [--dry-run] [-y]` | Convert existing repo to bare structure |
 61
 62### Clone workflows
 63
 64**Contributing to others' projects:**
 65
 66```
 67wt c https://github.com/org/repo.git
 68# origin → upstream, your remotes added from config
 69```
 70
 71**Your own projects:**
 72
 73```
 74wt c git@github.com:you/repo.git --own
 75# First configured remote becomes origin
 76```
 77
 78### Adding worktrees
 79
 80From inside an existing worktree, hooks from `.wt.lua` run automatically:
 81
 82```
 83cd project/main
 84wt a feature/new-thing -b              # New branch from current HEAD
 85wt a bugfix/issue-123 -b origin/main   # New branch from specific start point
 86wt a existing-branch                   # Checkout existing branch
 87```
 88
 89## Configuration
 90
 91### Global config (`~/.config/wt/config.lua`)
 92
 93```lua
 94return {
 95    branch_path_style = "nested",  -- or "flat"
 96    flat_separator = "_",          -- separator for flat style
 97
 98    remotes = {
 99        github = "git@github.com:myuser/${project}.git",
100        gitlab = "git@gitlab.com:myuser/${project}.git",
101    },
102
103    default_remotes = "prompt",    -- or {"github", "gitlab"}
104}
105```
106
107### Project config (`.wt.lua` in project root)
108
109```lua
110return {
111    hooks = {
112        copy = {".env.example", "Makefile.local"},
113        symlink = {".env", "node_modules"},
114        run = {"make setup", "npm install"},
115    }
116}
117```
118
119Hooks only run when `wt a` is executed from inside an existing worktree.
120You'll be prompted once per project to allow hooks; permissions are stored in
121`~/.local/share/wt/hook-dirs.lua`.
122
123## Dependencies
124
125- [gum](https://github.com/charmbracelet/gum) — interactive prompts
126
127## Contributions
128
129Patch requests are in
130[amolith/catchall](https://pr.pico.sh/r/amolith/catchall) on
131[pr.pico.sh](https://pr.pico.sh). You don't need a new account to
132contribute, you don't need to fork this repo, you don't need to fiddle
133with `git send-email`, you don't need to faff with your email client to
134get `git request-pull` working...
135
136You just need:
137
138- Git
139- SSH
140- An SSH key
141
142```
143# Clone this repo, make your changes, and commit them
144# Create a new patch request with
145git format-patch origin/main --stdout | ssh pr.pico.sh pr create amolith/catchall
146# After potential feedback, submit a revision to an existing patch request with
147git format-patch origin/main --stdout | ssh pr.pico.sh pr add {prID}
148# List patch requests
149ssh pr.pico.sh pr ls amolith/catchall
150```
151
152See "How do Patch Requests work?" on [pr.pico.sh](https://pr.pico.sh)'s home
153page for a more complete example workflow.
154
155---
156
157Some other tools if this one interested you
158
159- [agent-skills](https://git.secluded.site/agent-skills) - collection of Agent Skills for extending LLM capabilities
160- [garble](https://git.secluded.site/garble) - transform stdin with an LLM (fix typos, translate, reformat)
161- [formatted-commit](https://git.secluded.site/formatted-commit) - CLI that turns LLM input into well-formatted Conventional Commits