Metadata-Version: 2.5
Name: gittwin
Version: 0.2.0
Summary: Run multiple git commits, branches, or tags of the same app side by side in isolated environments
Project-URL: Homepage, https://github.com/Shyam-Sundar-Reddy/GitTwin
Project-URL: Repository, https://github.com/Shyam-Sundar-Reddy/GitTwin
License: MIT
License-File: LICENSE
Requires-Python: >=3.12
Requires-Dist: psutil>=5.9
Requires-Dist: rich>=13.0
Requires-Dist: typer>=0.12
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == 'dev'
Description-Content-Type: text/markdown

# GitTwin

Run multiple git commits, branches, or tags of the same FastAPI application
side by side, each in its own isolated environment — for comparison,
debugging, regression testing, and demonstrations.

**Status: working MVP.** `gittwin run`/`gittwin compare` actually boot real
FastAPI apps today. Framework support is currently **FastAPI only** — see
[Supported frameworks](#supported-frameworks) below.

## Why

Reproducing "it worked on commit X but not on commit Y" usually means
stashing changes, checking out refs one at a time, and juggling ports,
dependencies, and env files by hand. GitTwin makes that a single command:

```bash
gittwin compare HEAD abc123
```

```text
HEAD      -> http://127.0.0.1:8000
abc123    -> http://127.0.0.1:8001
```

Under the hood, each ref gets its own [git
worktree](https://git-scm.com/docs/git-worktree), its own `uv`-managed
virtual environment with its own dependencies installed, and its own port
— so multiple versions of your app run side by side without one clobbering
another or disturbing your current branch.

## Install

```bash
uv add gittwin
pip install gittwin
```

## Usage

```bash
gittwin run <ref>                  # launch one ref, prints its URL
gittwin compare <ref1> <ref2> ...  # launch two or more refs side by side
gittwin list                       # list worktrees gittwin has created
gittwin stop <ref>                 # stop one running instance
gittwin clean                      # stop everything, remove all worktrees/envs
gittwin doctor                     # check git and uv are installed
gittwin about
gittwin --version
```

`<ref>` accepts any commit SHA, branch name, or tag. An invalid ref fails
immediately with a clear error instead of a raw git traceback.

### Example

```bash
cd my-fastapi-project
gittwin compare HEAD main
# HEAD: creating worktree...
# main: creating worktree...
# HEAD: creating environment...
# main: creating environment...
# HEAD: installing dependencies...
# main: installing dependencies...
# HEAD: starting on port 8000...
# main: starting on port 8001...
# ┌──────┬───────────────────────┐
# │ Ref  │ URL                   │
# ├──────┼───────────────────────┤
# │ HEAD │ http://127.0.0.1:8000 │
# │ main │ http://127.0.0.1:8001 │
# └──────┴───────────────────────┘

gittwin clean   # tear both down when you're done
```

## Supported frameworks

**FastAPI only, for now.** `gittwin run`/`gittwin compare` detect FastAPI
via a `fastapi` entry in your `pyproject.toml` dependencies, and boot your
app with `uvicorn <module>:<app>` (convention: `main:app`). Flask, Django,
Node.js, Docker-based apps, and other languages are on the backlog, not
implemented yet.

## How it works

- **Worktrees**: each ref is checked out into `<repo>/.gittwin/worktrees/<ref>`,
  so multiple refs can be checked out simultaneously without one clobbering
  another. `gittwin list` shows only worktrees gittwin created — your main
  checkout is never listed as one of them.
- **Environments**: each worktree gets its own `uv`-managed venv under
  `<repo>/.gittwin/envs/<ref>`, with that ref's own `pyproject.toml`
  dependencies installed into it — so different refs can depend on
  different (even incompatible) package versions.
- **Ports**: each instance gets a free port automatically, allocated from
  `gittwin.toml`'s configured range (default `8000`-`8999`), with no
  collisions even when launching several refs concurrently via `compare`.
- **Cleanup**: `gittwin stop <ref>` / `gittwin clean` terminate the running
  process(es) and remove the worktree(s) and env(s) they used. If setup for
  a ref fails partway through, gittwin removes that worktree again rather
  than leaving a half-provisioned one behind.

## Development

This project uses [uv](https://docs.astral.sh/uv/) for dependency management.

```bash
uv sync --extra dev   # install package + dev deps into .venv
uv run pytest -q      # run tests
uv run gittwin about  # run the CLI
```
