Metadata-Version: 2.4
Name: tgbender-wt
Version: 0.1.0
Summary: Python Git worktree manager using a bare repository layout.
Keywords: git,worktree,dotfiles,cli
Author: Travis Bender
License-Expression: MIT
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Version Control :: Git
Classifier: Topic :: Utilities
Requires-Dist: platformdirs>=4.0,<5.0
Requires-Dist: prompt-toolkit>=3.0,<4.0
Requires-Dist: rich>=14.0,<15.0
Requires-Dist: tomlkit>=0.14.0,<0.15.0
Requires-Dist: typer>=0.20,<1.0
Requires-Python: >=3.12
Description-Content-Type: text/markdown

# wt

`wt` is a Python CLI for working in Git branches as separate directories.

It is built around a compact workflow:

```sh
wt c git@github.com:tgbender/project.git
cd project/main
wt a feat-login -b
wt l
wt r feat-login -b -f
```

The PyPI package name is `tgbender-wt`; the installed command is `wt`.

## Status

`0.1.0` is usable alpha software. The core flows are covered by integration tests and dogfooding, especially dirty worktree removal, stash recovery, templates, config, init/deinit recovery, and `wt doctor`.

## Install

```sh
uv tool install tgbender-wt
```

From a local checkout:

```sh
uv tool install .
```

## Commands

| Command                      | Alias  | Purpose                                                       |
| ---------------------------- | ------ | ------------------------------------------------------------- |
| `wt clone <url>`             | `wt c` | Clone a repo into a wt-managed worktree project.              |
| `wt new <name>`              | `wt n` | Create a new empty project.                                   |
| `wt add [branch]`            | `wt a` | Add a worktree, prompting for a branch if omitted.            |
| `wt add <branch> -b [start]` | `wt a` | Create a branch and worktree.                                 |
| `wt remove [branch]`         | `wt r` | Remove a worktree, or select one interactively.               |
| `wt list`                    | `wt l` | List managed worktrees.                                       |
| `wt fetch`                   | `wt f` | Fetch/prune configured remotes.                               |
| `wt init`                    |        | Convert a normal checkout into a wt-managed project.          |
| `wt deinit`                  |        | Convert a wt-managed project back to a normal checkout.       |
| `wt abort`                   |        | Recover the latest incomplete topology operation.             |
| `wt doctor`                  |        | Check layout, worktrees, refs, state, hooks, and CAS objects. |
| `wt stash ...`               |        | Manage searchable wt stashes.                                 |
| `wt config ...`              |        | Inspect and edit configuration.                               |

## Worktrees

Create a new branch from the current worktree:

```sh
wt a feat-login -b
```

Prompt for a branch and parent:

```sh
wt a -b
```

Create from a specific start point:

```sh
wt a fix-prod -b origin/main
```

Check out an existing branch:

```sh
wt a release-2026-05
```

Branches map to paths using the configured path style:

```toml
branch_path_style = "nested" # feat/login -> feat/login
branch_path_style = "flat"   # feat/login -> feat_login
flat_separator = "_"
```

## Remove Without Losing Work

`wt remove` is conservative by default.

```sh
wt r
wt r feat-login
wt r feat-login -f
wt r feat-login -b -f
wt r feat-login --discard
```

- No branch argument opens an interactive selector.
- `-f` / `--force` auto-saves dirty tracked, untracked, and ignored files into a wt stash before removing the worktree.
- `-b` / `--branch` also deletes the Git branch.
- `--discard` / `--no-save` is the explicit destructive option.

So `wt r feat-login -b -f` means: save dirty work if needed, remove the worktree, then delete the branch.

## Stash

`wt stash` stores metadata in SQLite so stashes are named, searchable, and tied back to branches/worktrees.

```sh
wt stash
wt stash --name login-wip -m "before cleanup" -t login
wt stash save login-wip -u -m "before cleanup" -t login
wt stash list
wt stash search login
wt stash show login-wip
wt stash apply login-wip
wt stash drop login-wip
```

Bare `wt stash` is the auto flow: it saves tracked, untracked, and ignored changes using the current branch as the default name. Use `--tracked-only` if you only want tracked modifications.

Tracked changes are stored behind private Git refs under `refs/wt-stash/<id>` and backed up as binary patches under `.wt/patches/`.
Large untracked or ignored files over 4 MiB are stored in wt CAS under `.wt/objects/sha256/`.

`drop` and `pop` hide stashes from default listings but keep the backend data recoverable by id:

```sh
wt stash list --all
wt stash apply <id> --dropped
```

## Init, Deinit, Abort

Convert a normal checkout:

```sh
wt init --plan
wt init --apply -y
```

Convert back:

```sh
wt deinit --plan
wt deinit --apply -y
```

Recover an interrupted topology operation:

```sh
wt abort
```

Topology-changing commands use preflight checks, persisted plans, transaction records, and recovery manifests. `wt doctor` is the first thing to run when a project looks inconsistent.

## Config

Configuration is TOML and layered from global to project-local:

```sh
wt config init
wt config show
wt config get branch_path_style
wt config set branch_path_style flat
```

Common config:

```toml
branch_path_style = "flat"
flat_separator = "-"
default_remotes = "prompt"

[remotes]
github = "git@github.com:tgbender/${project}.git"
```

## Templates

Files in `.wt/templates/` are copied into new worktrees without overwriting existing files. Symlinks are preserved.

```text
.wt/templates/
  .env.example
  .vscode/settings.json
```

## Development

```sh
mise run setup
mise run check
```

Direct checks:

```sh
uv run pytest
uv run --with ruff ruff check .
uv run mypy src
uv build
```

## License

MIT.
