Skip to main content

Add your description here

Project description

workstack

A global git worktree manager that enables the management of multiple git worktrees to parallelize development, primarily for agentic workflows.

Manage git worktrees and Graphite (gt) stacks in a centralized directory with automatic environment setup and per-worktree configuration.

Why?

Traditional git workflows involve switching branches in a fixed repo at a single file location. This worked well for human workflows, as humans can typically only work on one thing at a time. With the emergence of coding agents, there is now a new need for maintaining parallel copies of repos. git has worktrees to enable this use case, but managing them is tedious and error-prone. workstack is designed to have a simple, opinionated workflow around the creation of worktrees that allows fast switching and easy management. It was designed to be used for Python projects managed via uv (it relies on fast environment creation) and for projects that use gt (Graphite) to manages "stacks", but could be fairly easily generalized by a motivated user. It does fallback to git-only operations when gt is not available.

How it works

You configure a single location for all you worktress (e.g. ~/workstack/worktrees). As you use workstack it creates a folder per repository.

  • Centralizes worktrees in ~/worktrees/<repo>/<feature>/ (configurable).
  • Auto-configures environments with .env, virtual environments, and activation scripts. When you switch environments you can set new environment variables and run scripts for setup.
  • CRUD operations via the cli: create, ls, rm workstacks
  • Fast switching: Fast switching via the switch command.
  • Integrates with AI assistants via .PLAN.md file support
  • Works with Graphite for stacked diffs (optional)

Installation

# With uv (recommended)
uv tool install workstack

# From source
uv tool install git+https://github.com/schrockn/workstack.git

Quick Start

# 1. Initialize in your repository
cd /path/to/your/repo
workstack init

# 2. Create a worktree
workstack create user-auth

# 3. Switch to it (workstack switch user-path prints out the below for easy copy pasting)
source <(workstack switch user-auth --script)

# 4. Work on your feature...

# 5. Switch back
source <(workstack switch . --script)

# 6. Clean up
workstack rm user-auth

Plan-oriented development

workstack comes with a simple, but opinionated workflow for plan-based development. The idea:

  • Plan in master/main. Leave all work for worktress. Since planning is read-only, you can do planning in parallel without creating multiple worktrees.
  • Make the plan: Prompt your agent to create a plan, iterate on it, and then save it as a md file at repo root.
  • Execute the plan: Then create a workstack to execute the plan. workstack create --plan your_plan.md will
    • Automatically create a workstack. Name it based on the name of the plan file.
    • It will move the plan to the workstack with the name .PLAN.md. On init workstack adds this filename to your .gitignore. We have found the checking in planning files confuses reviews and adds excessive bookkeeping. This way the agent has access to the plan without polluting source control.
  • Switch quickly: You can switch worktrees quickly. Python requires you to source an shell script to activate a virtual environment, so this forces a level of indirection. We recommend either:
    • workstack switch . prints out source <(workstack switch . --script) which you can copy and paste or workstack switch . | pbcopy
  • Move branches to a different worktree: This is annoying without workstack because two worktrees cannot point to the same branch. This handles the swapping for you.

Core Concepts

Architecture

~/.workstack/config.toml          # Global config (worktree root location)
~/worktrees/
  your-repo/
    config.toml                   # Repo-specific config
    user-auth/                    # Worktree
      .git, .env, .venv/, activate.sh, .PLAN.md, <source>
    refactor-api/
      ...

Configuration

Global (~/.workstack/config.toml):

workstacks_root = "/Users/you/worktrees"
use_graphite = true  # Auto-detected (requires gt CLI)

Per-Repo (~/worktrees/<repo>/config.toml):

[env]
# Variables: {worktree_path}, {repo_root}, {name}
DATABASE_URL = "postgresql://localhost/{name}_db"

[post_create]
shell = "bash"
commands = [
  "uv venv",
  "uv pip install -e .",
]

Commands

workstack init [--preset auto|generic|dagster]

Initialize workstack for current repository. Creates config, adds to .gitignore.

workstack create NAME [--branch BRANCH] [--ref REF] [--plan FILE]

Create worktree with new branch.

workstack create feature-x                          # Branch: work/feature-x
workstack create fix --branch hotfix/bug --ref main
workstack create --plan Add_Auth.md                 # Moves plan to .PLAN.md

workstack co BRANCH [--name NAME]

Checkout existing branch into worktree.

workstack co feature/login
workstack co feature/login --name login-work

workstack move [NAME] [--to-branch BRANCH]

Move current branch to worktree, switch to different branch.

workstack move                     # Move to worktree, switch to main
workstack move feat --to-branch develop

workstack switch NAME [--script]

Switch to worktree (or . for root repo).

source <(workstack switch feature-x --script)
source <(workstack switch . --script)

Alias:

alias ws='source <(workstack switch --script'

workstack list / workstack ls

List all worktrees.

workstack rm NAME [-f]

Remove worktree (with optional force).

workstack completion [bash|zsh|fish]

Generate shell completions.

source <(workstack completion bash)  # Add to ~/.bashrc

Workflows

AI Development with Claude

# 1. Create plan (Claude generates this)
claude "Create plan for user auth"  # Saves Add_User_Auth.md

# 2. Create worktree from plan
workstack create --plan Add_User_Auth.md

# 3. Switch and launch Claude
source <(workstack switch add-user-auth --script)
claude  # Reads .PLAN.md automatically

Parallel Features

workstack create feature-a
source <(workstack switch feature-a --script)
# ... work ...

workstack create feature-b
source <(workstack switch feature-b --script)
# ... work ...

source <(workstack switch feature-a --script)  # Back to A

Testing PRs

git fetch origin pull/123/head:pr-123
workstack co pr-123
source <(workstack switch pr-123 --script)
pytest
workstack rm pr-123 -f

Repository-Specific Setup

Django:

[env]
DATABASE_URL = "postgresql://localhost/myproject_{name}"

[post_create]
shell = "bash"
commands = [
  "python -m venv .venv",
  "source .venv/bin/activate && pip install -e .[dev]",
  "createdb myproject_{name}",
  "python manage.py migrate",
]

Dagster:

[env]
DAGSTER_GIT_REPO_DIR = "{worktree_path}"

[post_create]
shell = "bash"
commands = ["uv venv", "uv run make dev_install"]

Environment Variables

Template Variables (use in config.toml):

  • {worktree_path} - Absolute path to worktree
  • {repo_root} - Absolute path to repository root
  • {name} - Worktree name

Always Available (exported in activate.sh):

  • WORKTREE_PATH, REPO_ROOT, WORKTREE_NAME

Graphite Integration

If Graphite CLI (gt) is installed, workstack uses gt create instead of git branch for new worktrees, ensuring proper stack tracking.

brew install withgraphite/tap/graphite
workstack init  # Auto-detects gt

Manual override in ~/.workstack/config.toml:

use_graphite = false  # Disable even if gt is installed

Tips

Shell aliases:

alias ws='source <(workstack switch --script'
alias wc='workstack create'
alias wl='workstack list'
source <(workstack completion bash)

Naming: Use lowercase with hyphens: add-user-auth, fix-login-bug

Cleanup: workstack listworkstack rm old-feature -f

Development

git clone https://github.com/schrockn/workstack.git
cd workstack
uv sync --group dev
uv run pytest
uv run ruff check
uv run pyright

FAQ

vs git worktree? Adds centralized management, auto environment setup, templates, and AI integration.

Python version? 3.13+ (earlier may work).

Non-Python projects? Yes! Configure post_create for any stack.

Without Graphite? Works fine, uses standard git commands.

Links

License

MIT - Nick Schrock (@schrockn)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

workstack-0.1.1.tar.gz (30.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

workstack-0.1.1-py3-none-any.whl (17.1 kB view details)

Uploaded Python 3

File details

Details for the file workstack-0.1.1.tar.gz.

File metadata

  • Download URL: workstack-0.1.1.tar.gz
  • Upload date:
  • Size: 30.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.2

File hashes

Hashes for workstack-0.1.1.tar.gz
Algorithm Hash digest
SHA256 02c5eaad19c8cec966035d00533fd4a91fc1646e8f4f23726ff7c1d991718755
MD5 f34e2df609456c0a45cbe1c109a80a0f
BLAKE2b-256 a81c5c8ec02c636885ad7f122c1ec904e87c9b6a0699a4ba748a0f16593de82d

See more details on using hashes here.

File details

Details for the file workstack-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: workstack-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 17.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.2

File hashes

Hashes for workstack-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8d9123fff7dfa0b3a0424fc7d5ff6e4f371b7e681d5804737314d8cd2d982f72
MD5 6dc060b69e354a2fee6a04574305146d
BLAKE2b-256 97c48ac14b0d730fb397a9744d377f1a22743690841edb59d193783ea4460841

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page