Use cases

First-time setup: a guided tour

You’ve installed Git Treeline and you’re looking at a project. This page walks through the full setup, section by section — what Treeline generates, what every config field does, and how to decide what your project needs. By the end you’ll have an isolated worktree running your app.

1. Install

# macOS / Linux (Homebrew)

$ brew install git-treeline/tap/git-treeline

# or from source

$ go install github.com/git-treeline/git-treeline@latest

Treeline is a single binary with no runtime dependencies. It works on macOS and Linux. Windows is supported for core features (ports, env, databases); the HTTPS subdomain router (gtl serve) is macOS/Linux only.

2. Run gtl install

$ cd your-project

$ gtl install

Detected Rails project

Wrote .treeline.yml

Created user config at ~/.config/git-treeline/config.yml

Post-checkout hook: .git/hooks/post-checkout

Allocated port 3000

Wrote .env.local

Local HTTPS routing lets you access worktrees at https://myapp-main.prt.dev

HTTPS router setup: Yes, install now

Ready. Run gtl start to start your server.

gtl install handles the full setup in one step:

  1. Generates config — detects your framework (Next.js, Vite, Rails, Express, Python, Rust, Go) and creates a tailored .treeline.yml with agent context in AGENTS.md
  2. Creates user config if this is your first project on the machine
  3. Installs the post-checkout hook so future checkouts auto-allocate resources
  4. Allocates ports and writes env for the current worktree
  5. Offers HTTPS routing (optional) — trusts a local CA and sets up port forwarding. Skip this if you only need localhost.

Every step is idempotent — safe to re-run any time. If you already have a .treeline.yml, it skips config generation and goes straight to allocation and setup.

For fine-grained control, gtl init generates just the config file without running setup. Use --project myapp to set the project name, --template-db myapp_dev for database template, or --skip-agent-config to skip agent context.

3. Tour the generated config

Here’s a fully loaded .treeline.yml. Your generated file will be simpler — init only includes what it detects. Let’s walk through each section so you know what’s available and when you’d add it.

.treeline.yml (annotated)
# --- Identity ---
project: myapp
merge_target: develop

# --- Ports ---
port_count: 2

# --- Environment ---
env_file: .env.local

env:
  PORT: "{port}"
  ESBUILD_PORT: "{port_2}"
  DATABASE_NAME: "{database}"
  DATABASE_URL: "postgresql://localhost:5432/{database}"
  REDIS_URL: "{redis_url}"
  APPLICATION_HOST: "localhost:{port}"

# --- Database ---
database:
  adapter: postgresql
  template: myapp_development
  pattern: "{template}_{worktree}"

# --- Files ---
copy_files:
  - config/master.key

# --- Commands ---
commands:
  setup:
    - bundle install --quiet
    - yarn install --silent
  start: bin/dev

# --- Lifecycle hooks ---
hooks:
  pre_setup:
    - psql -lqt | grep myapp_development
  post_setup:
    - echo "Ready"

# --- Aliases ---
aliases:
  mailhog: 8025
  sidekiq: 9292

# --- Editor ---
editor:
  title: "{project} ({branch}) — {url}"
  color: auto
  theme: GitHub Dark

project

The name used in the registry, in branch URLs (myapp-feature-auth.prt.dev), and as a namespace for port reservations. Defaults to the directory name. Most projects never change this.

merge_target

The branch that gtl prune --merged checks against. Treeline auto-detects this from your git remote — you only need to set it if your repo uses something other than main/master (e.g. develop, staging).

port_count

How many contiguous ports each worktree gets. Default is 1. Set it higher when your app needs multiple ports — Rails with esbuild needs 2 (one for the server, one for the asset builder), a full-stack monolith with a separate WebSocket server might need 3.

Ports are allocated in blocks. If port_count: 2 and the base is 3002, the first worktree gets 3002–3003, the next gets 3012–3013 (based on the increment in your user config).

env_file

Where Treeline writes the env file. Usually .env.local (Next.js, Vite) or .env (Express, Rails). If the source file you want to seed from has a different name, use the extended form:

env_file:
  path: .env
  seed_from: .env.example

env

Key-value pairs written to the env file. Values support interpolation tokens that Treeline resolves at setup time:

Token Resolves to
{port} First allocated port
{port_N} Nth allocated port (e.g. {port_2})
{database} Cloned database name
{redis_url} Full Redis URL with namespace
{redis_prefix} Redis key prefix (prefixed strategy)
{project} Project name
{worktree} Worktree directory name
{router_url} HTTPS URL for this worktree (e.g. https://myapp-feature.prt.dev)
{router_domain} Router domain (e.g. prt.dev) — for cookie domains, config.hosts, etc.
{resolve:project} URL of another project’s allocation (same branch)
{resolve:project/branch} URL of another project’s allocation on a specific branch

database

Entirely optional. If your project doesn’t use a local database, or you handle database creation in commands.setup, omit this whole block.

When present, Treeline clones a database per worktree at setup time:

The template database is never modified. Use gtl db reset to re-clone, gtl db restore dump.sql to load from a dump, and --drop-db with gtl release to clean up. For a deep dive, see Database per branch.

copy_files

Files copied from the main repo directory into each new worktree. Typically secrets that aren’t in version control — config/master.key, .env.secret, certificates. Treeline copies them during setup so the worktree has everything it needs to boot.

commands.setup

Shell commands that run inside the worktree after the env file is written. Install dependencies, run migrations, seed data — whatever your project needs. They run in order and have access to the env vars Treeline just wrote ($PORT, $DATABASE_URL, etc.).

commands.start

Whatever you’d type to boot the app. bin/dev, npm run dev, foreman start, cargo run. Used by gtl start and the --start flag on gtl new and gtl review. The server runs under a lightweight supervisor that agents and scripts can control via gtl stop / gtl restart.

hooks

Lifecycle hooks for validation and cleanup. Four hook points:

Hook When On failure
pre_setup Before commands.setup Aborts setup
post_setup After all setup Warns, continues
pre_release Before resource release Aborts release
post_release After resource release Warns, continues

Use pre_setup to gate on prerequisites (template database must exist, secrets must be present). Use post_release for cleanup like notifying a monitoring service or removing cloud resources.

aliases

Project-level service aliases for the HTTPS router. If your team runs Mailhog on :8025 and Sidekiq web on :9292, define them here and everyone gets https://mailhog.prt.dev and https://sidekiq.prt.dev automatically. For personal tools, use gtl serve alias instead. See Named URLs for local services.

editor

Optional visual cues so you can tell worktree windows apart at a glance:

4. Your machine config

.treeline.yml describes the project. Your user config (config.json) describes your machine — how ports are allocated, where worktrees go, which editor you use. It lives at:

gtl install creates this automatically if it doesn’t exist. You can also run gtl config to see or modify it. Here are the key sections:

Port allocation

config.json (partial)
{
  "port": {
    "base": 3002,
    "increment": 2,
    "reservations": {
      "myapp": 3010,
      "myapp/staging": 3020
    }
  }
}

base is where dynamic allocation starts (3002 by default — ports 3000 and 3001 are reserved for gtl proxy and the HTTPS router). increment controls the gap between allocations. reservations pin specific projects or branches to stable ports — useful for long-lived worktrees that other services depend on.

# Pin your main repo to port 3010

$ gtl config set port.reservations.myapp 3010

# Pin the staging worktree to 3020

$ gtl config set port.reservations.myapp/staging 3020

Worktree path

By default, gtl new creates worktrees as siblings of the repo (../myapp-feature-x). If you prefer worktrees inside the repo:

config.json (partial)
{
  "worktree": {
    "path": ".worktrees/{branch}"
  }
}

Supports {project} and {branch} interpolation. If the path is inside the repo, Treeline ensures it’s in .gitignore automatically.

Redis

If your project uses Redis, Treeline can namespace each worktree to prevent key collisions. Prefixed (default) namespaces keys under myapp:feature-x:... in a shared DB 0. Database gives each worktree its own Redis DB number (1–15). Set redis.strategy in your user config. Most teams never change this.

5. Create your first worktree

$ gtl new feature-auth --start

Creating worktree feature-auth

Allocated ports 3002, 3003

Cloned database myapp_development_feature_auth

Copied config/master.key

Wrote .env.local

Running setup: bundle install --quiet

Running setup: yarn install --silent

==> https://myapp-feature-auth.prt.dev

Starting: bin/dev (port 3002)

One command: worktree created, ports allocated, database cloned, env file written, files copied, setup commands run, server booted. The --start flag kicks off the server under the supervisor immediately.

If you already have a worktree (e.g. from git worktree add), use gtl setup <path> to allocate resources for it. Going forward, the post-checkout hook installed by gtl install handles this automatically for new checkouts.

6. Verify everything works

$ gtl doctor

Config:

  ✓ .treeline.yml found

  ✓ User config loaded

  ✓ post-checkout hook installed

Allocation:

  ✓ Ports 3002-3003 allocated

  ✓ Database myapp_development_feature_auth exists

  ✓ Redis namespace assigned

Runtime:

  ✓ Server listening on :3002

  ✓ .env.local matches allocation

gtl doctor checks config, allocation, and runtime. If something is wrong — missing template database, port conflict, stale env file — it tells you exactly what to fix. Add --json for structured output.

7. What to commit

File Commit? Why
.treeline.yml Yes Project config — shared with the team
AGENTS.md Yes Agent context — tells AI agents how to use ports
config.json No Per-machine settings — lives outside the repo
registry.json No Allocation ledger — lives outside the repo

Once you commit .treeline.yml and AGENTS.md, every teammate who installs gtl can run gtl new <branch> --start and get a fully isolated environment. See New developer, one command for that walkthrough.

What’s next

You have a working config and your first worktree. From here, the depth you go depends on your project:

All use cases