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,rmworkstacks - Fast switching: Fast switching via the
switchcommand. - Integrates with AI assistants via
.PLAN.mdfile 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
mdfile at repo root. - Execute the plan: Then create a
workstackto execute the plan.workstack create --plan your_plan.mdwill- 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
initworkstack 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 outsource <(workstack switch . --script)which you can copy and paste orworkstack switch . | pbcopy
- Move branches to a different worktree: This is annoying without
workstackbecause 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 list → workstack 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
- PyPI: https://pypi.org/project/workstack/
- GitHub: https://github.com/schrockn/workstack
- Issues: https://github.com/schrockn/workstack/issues
License
MIT - Nick Schrock (@schrockn)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
02c5eaad19c8cec966035d00533fd4a91fc1646e8f4f23726ff7c1d991718755
|
|
| MD5 |
f34e2df609456c0a45cbe1c109a80a0f
|
|
| BLAKE2b-256 |
a81c5c8ec02c636885ad7f122c1ec904e87c9b6a0699a4ba748a0f16593de82d
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8d9123fff7dfa0b3a0424fc7d5ff6e4f371b7e681d5804737314d8cd2d982f72
|
|
| MD5 |
6dc060b69e354a2fee6a04574305146d
|
|
| BLAKE2b-256 |
97c48ac14b0d730fb397a9744d377f1a22743690841edb59d193783ea4460841
|