New developer, one command
A new teammate clones the repo. The README says “run these 14 steps.” Half are macOS-specific, two reference a database dump that doesn’t exist yet, and the env example file is three months stale. With Treeline in the repo, the README says gtl new main --start.
The scenario
Typical onboarding for a Rails or Next.js project involves: install dependencies, create a database, load the schema, seed data, copy and edit an env file, find an available port, wire up Redis, and start the server. Each step can fail for reasons unique to the developer’s machine. The .treeline.yml committed to the repo encodes all of this in a declarative config that gtl new executes in order.
The developer doesn’t need to understand worktrees to benefit. Their first environment is a worktree — it just happens to be the one they work in.
Step 1: The project maintainer sets up once
Run gtl install in the project root. It detects the framework, generates a .treeline.yml, creates user config, installs the post-checkout hook, allocates ports, writes env, and optionally sets up HTTPS routing. Commit the config.
$ 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
Ready. Run gtl start to start your server.
The resulting config declares everything the project needs:
project: myapp
port_count: 2
env_file: .env.local
database:
adapter: postgresql
template: myapp_development
pattern: "{template}_{worktree}"
copy_files:
- config/master.key
env:
PORT: "{port}"
DATABASE_NAME: "{database}"
REDIS_URL: "{redis_url}"
ESBUILD_PORT: "{port_2}"
APPLICATION_HOST: "localhost:{port}"
commands:
setup:
- bundle install --quiet
- yarn install --silent
start: bin/dev Step 2: A new developer joins
The new developer installs gtl, clones the repo, and runs one command. No manual port selection, no env file editing, no database creation.
$ brew install git-treeline/tap/git-treeline
$ git clone git@github.com:acme/myapp.git
$ cd myapp
$ gtl new main --start
Creating worktree main
Allocated ports 3002, 3003
Cloned database myapp_development_main
Wrote .env.local
Copied config/master.key
Running setup: bundle install --quiet
Running setup: yarn install --silent
==> https://myapp-main.prt.dev
Starting: bin/dev (port 3002)
Everything in the config happened in order: port allocation, database clone, env file generation, file copies, setup commands, and server boot. The developer is looking at a running app.
What gtl new actually does
One command, multiple steps — all derived from .treeline.yml:
| Step | What happens | Config source |
|---|---|---|
| 1 | Create git worktree | git worktree add |
| 2 | Allocate port block | port_count + user config range |
| 3 | Clone database (if configured) | database.template |
| 4 | Assign Redis namespace (if configured) | User config redis.strategy |
| 5 | Write env file with interpolated tokens | env_file + env |
| 6 | Copy files from main repo | copy_files |
| 7 | Run setup commands | commands.setup |
| 8 | Boot the server (if --start) | commands.start |
The post-checkout hook
gtl install sets up a post-checkout git hook. Every subsequent git checkout — or git worktree add — triggers resource allocation automatically. New worktrees get their own port, database, and env file without the developer running gtl setup manually.
The hook is idempotent: if resources are already allocated for the worktree, it’s a no-op.
Framework examples
gtl install auto-detects your framework and generates a tailored config. Here are common starting points:
Next.js
project: myapp
env_file: .env.local
env:
PORT: "{port}"
NEXT_PUBLIC_APP_URL: "http://localhost:{port}"
commands:
setup:
- npm install
start: npm run dev
Next.js loads .env.local but doesn’t use PORT for its listen port. Update your dev script: "dev": "next dev --port ${PORT:-3000}". gtl install prints this guidance automatically.
Vite (React, Vue, Svelte)
project: website
env_file: .env.local
env:
PORT: "{port}"
commands:
setup:
- npm install
start: npx vite --port {port}
Vite ignores the PORT env var, so the start command passes {port} directly. gtl install detects Vite and generates this automatically.
Express / Node
project: myapi
env_file: .env
env:
PORT: "{port}"
commands:
setup:
- npm install
start: node server.js Lifecycle hooks for validation
If onboarding has prerequisites — a database dump must exist, or a secret must be in the keychain — use hooks.pre_setup to fail fast:
hooks:
pre_setup:
- psql -lqt | grep myapp_development || echo "Template DB missing" && exit 1
post_setup:
- echo "Setup complete. Run gtl start to boot." pre_setup aborts on failure. post_setup warns but continues. Both run at setup time — before the server boots.
Verifying the setup
$ gtl doctor
Config:
✓ .treeline.yml found
✓ User config loaded
Allocation:
✓ Ports 3002-3003 allocated
✓ Database myapp_development_main exists
Runtime:
✓ Server listening on :3002
✓ .env.local matches allocation
gtl doctor checks config, allocation, and runtime state. If something is wrong, it tells the developer exactly what to fix. Add --json for structured output that AI agents and CI can parse.
Read next
- Database per branch — deep dive on clone, seed, and SQLite strategies
- Isolation feature page — ports, databases, Redis, and env files in detail
- Docs: configuration — full
.treeline.ymlreference - Docs: getting started — install and first worktree