--- title: Git worktrees description: Run agents in isolated git worktrees with setup hooks, scripts, and long-running services. nav: Git worktrees order: 11 category: Workspaces --- # Git worktrees Git worktrees are one kind of workspace. A [workspace](/docs/workspaces) is the place where a task happens. When that workspace is backed by a git worktree, Paseo creates a separate directory on a separate branch so parallel agents never step on each other. This page covers the git-specific details: where worktrees live, how branches are chosen, and how to configure setup hooks, scripts, terminals, and long-running services through `paseo.json`. ## Layout and workflow Worktrees live under `$PASEO_HOME/worktrees/` by default, grouped by a hash of the source checkout path. You can change the base directory with `worktrees.root` in `config.json`. Each worktree gets a random slug; the branch name is chosen when you first launch an agent. ``` ~/.paseo/worktrees/ └── 1vnnm9k3/ # hash of source checkout path ├── tidy-fox/ # worktree slug (branch set on first agent) └── bold-owl/ ``` With a custom root, Paseo keeps the same hashed layout under that directory: ```json { "worktrees": { "root": "/mnt/fast/paseo-worktrees" } } ``` 1. Create a worktree, Paseo runs your setup hooks 2. Launch an agent, a branch is created or assigned 3. Review the diff against the base branch 4. Merge or archive, archive runs teardown and removes the directory ## paseo.json Drop a `paseo.json` in your repo root. Paseo reads it from the committed version of the base branch you picked, so uncommitted changes in other branches don't apply. ```json { "worktree": { "setup": "npm ci", "teardown": "rm -rf .cache" }, "scripts": { "test": { "command": "npm test" }, "web": { "command": "npm run dev", "type": "service", "port": 3000 } } } ``` ## Setup and teardown `setup` runs once after the worktree is created. A fresh worktree has no installed dependencies and no ignored files (like `.env`), so use setup to install and copy what you need. `teardown` runs during archive, before the directory is removed. ```json { "worktree": { "setup": "npm ci\ncp \"$PASEO_SOURCE_CHECKOUT_PATH/.env\" .env\nnpm run db:migrate", "teardown": "npm run db:drop || true" } } ``` Both fields accept a multiline shell script or an array of commands; commands run sequentially either way. Commands run with the worktree as `cwd`. Use `$PASEO_SOURCE_CHECKOUT_PATH` to reach files in the original checkout (untracked config, local caches, etc). ## Scripts and services `scripts` are named commands you can run inside a worktree on demand. Mark one as a _service_ and Paseo supervises it as a long-running process, assigns it a port, and routes HTTP traffic to it through the daemon's reverse proxy. ### Plain scripts ```json { "scripts": { "test": { "command": "npm test" }, "lint": { "command": "npm run lint" }, "generate": { "command": "npm run codegen" } } } ``` ### Services ```json { "scripts": { "web": { "type": "service", "command": "npm run dev -- --port $PASEO_PORT", "port": 3000 }, "api": { "type": "service", "command": "npm run api -- --port $PASEO_PORT" } } } ``` Omit `port` to let Paseo auto-assign one. Bind your process to `$PASEO_PORT` rather than hard-coding, each worktree gets a distinct port so multiple copies of the same service coexist. ### Reverse proxy Every service is reachable through the daemon at a deterministic hostname: ``` http://