Worktree provisioner
Run every branch at the same time
Declare what each branch needs in one YAML file: ports, databases, routing, env, lifecycle hooks. GTL provisions it. Three features, a bugfix, and a code review, all at once.
brew install git-treeline/tap/git-treeline v0.41.0
Single command setup: gtl install handles config, hooks, ports, and optional HTTPS routing.
Get started →
A git worktree is a separate checkout of your repo in its own directory — git worktree add creates one in seconds. But every checkout shares the same ports, databases, and config.
~/feature-a $ npm run dev
▸ Ready on http://localhost:3000
~/feature-b $ bin/dev
Error: listen EADDRINUSE : :3000
~/feature-b $ psql -c "CREATE DATABASE myapp_dev"
ERROR: database "myapp_dev" already exists
~ $ gtl new feature-auth
Creating worktree feature-auth
Allocated port 3010
Cloned database myapp_dev_feature_auth
Wrote .env.local
Running setup commands...
==> https://myapp-feature-auth.prt.dev
named URL via gtl serve (one-time setup)
Your worktrees should be provisioned, not duct‑taped.
OAuth providers, Stripe webhooks, Mapbox, CORS policies — they’re all registered to localhost:3000. The moment a second branch takes that port, every integration breaks. Treeline never allocates common ports. It reserves them for the proxy.
$ gtl proxy 3000
Proxying :3000 → :4010 (feature-auth)
# OAuth callback → :4010
# Stripe webhook → :4010
# Mapbox origin → :4010
Configure once, never again
Register localhost:3000/callback in your OAuth dashboard. Register localhost:3000/webhooks in Stripe. Done.
Switch what’s behind it
gtl proxy 3000 routes to whichever worktree you’re in. The external world sees the same origin. You rotate what’s behind it.
Branch URLs for everything else
Your browser uses myapp-feature.prt.dev. Third-party services use port 3000. Both work at the same time.
Everything is driven by .treeline.yml at the root of your repo. Each feature page goes deeper: config options, terminal walkthroughs, and edge cases.
Not containers — separate ports, databases, and config for every worktree. Declare what each branch needs in .treeline.yml and a git hook installed by gtl install allocates resources on every checkout.
Environment isolation
$ gtl new feature-auth
Allocated port 3010
Cloned database myapp_dev_feature_auth
Wrote .env.local
==> https://myapp-feature-auth.prt.dev
named URL via gtl serve
Your app still listens on localhost:{port} but the router gives every branch a named HTTPS URL so you don’t need to remember which port is which. Port 3000 stays free for gtl proxy so OAuth, Stripe, and CORS stay configured to a single origin.
Networking
localhost:3010 Ephemeral port
https://myapp-feature-auth.prt.dev HTTPS URL for this branch
gtl review 42 fetches a PR and boots the app in one command. A lightweight process supervisor handles start, stop, and restart — no PID files, no signal guessing.
Workflows
$ gtl review 42 --start
named URL via gtl serve
A built-in MCP server — the protocol AI coding agents use to call tools — lets agents query real port allocations, control the dev server, and inspect config. Works with any MCP-compatible editor.
AI Agents
{
"mcpServers": {
"gtl": {
"command": "gtl",
"args": ["mcp"]
}
}
} Two ways to view your worktrees: a macOS menu bar app for quick access, or a full-screen terminal dashboard for keyboard-driven control.
Detailed walkthroughs for the scenarios that break multi-branch development.
Guide
Install, configure, and create your first isolated worktree. The full walkthrough.
Networking
OAuth, Stripe, and CORS all expect localhost:3000. Here’s why that still works.
Isolation
Clone from a template in seconds, seed from hooks, or copy a SQLite file.
brew install git-treeline/tap/git-treeline Also go install or a release binary.