项目

Worktree

每个 git worktree 一个环境:拥有自己的域名、端口、.env 和数据库,让多个分支(或多个编程智能体)并行运行。

git worktree 是仓库的第二份工作副本,位于另一个分支、另一个文件夹中。Joppa 把它变成一个 环境:同一个应用,拥有自己的域名、自己的端口、自己的 .env,如果你愿意,还可以有自己的数据库。你可以让 main 保持在线,同时让一个分支(或 Claude Code 这样的智能体)在旁边工作,不会有端口或数据冲突。

项目的 Worktree 标签页(W)列出它的 worktree。项目文件夹是 git 仓库时才会显示该标签页。

Worktree 标签页:项目的 worktree、它们的域名和状态

worktree 会得到什么

域名

分支名会成为域名中的一级标签:feature/Login UI 变为 feature-login-ui(游离的 worktree 使用其文件夹名)。

项目域名 worktree 域名
myproject.test feature-login-ui.myproject.test
app.myproject.test app.feature-login-ui.myproject.test

如果这个名称已被占用(例如分支 api,而项目已有 api.myproject.test),Joppa 会加上编号:api-2。证书会自动覆盖这些域名,无需任何操作。只有指向项目开发服务器的域名才会被沿用。

端口

每个开发服务器都会获得自己的端口:项目的端口 + 100、+ 200……(5173 → 5273),否则使用 41000 到 49999 之间的空闲端口。绝不会使用其他项目的端口,也不会使用已被占用的端口。

Joppa 会以服务器能理解的方式把端口传给它:

  1. Joppa 本来就会赋值的变量(脚本中的 ${PORT:-3000},php artisan serve 的 SERVER_PORT,Reverb 的 REVERB_SERVER_PORT);
  2. 服务器读取的变量(代码中的 API_PORT,.env 中的 PORT);
  3. 脚本中写明的端口(vite --port 5173),会被改写;
  4. 对 Vite、Astro、Next.js、Nuxt、Angular、Wrangler、Storybook、Vue CLI、Docusaurus、Gatsby、VitePress 和 Expo 使用 --port(同时设置 PORT);对 Create React App 使用 PORT。

如果服务器的端口只写死在代码里、没有变量,就无法迁移:Joppa 会把它从「全部启动」中取消勾选,并提示你。

如果服务器从带默认值的变量中读取另一个服务器的地址(process.env.API_URL ?? "http://localhost:47400"),它会收到新的地址:worktree 的前端与 worktree 的 API 通信,而不是项目的 API。

Docker Compose 服务仍属于项目:worktree 直接使用它们,不会启动第二份副本(它们的端口是固定的)。

.env

git 不会复制它忽略的文件。Joppa 会把 worktree 缺少的这些文件复制进去:.env、.env.local、.env.development、.env.development.local、.dev.vars(Wrangler)和 .php.ini,以及未提交的版本固定文件(.php-version、.node-version、.nvmrc、.tool-versions),包括根目录和每个开发服务器的文件夹。其中的地址会被替换:localhost:5173 → localhost:5273,VITE_PORT=5173 → 5273,https://app.myproject.test → https://app.feature-login-ui.myproject.test。

数据库

对于项目在 Joppa 服务 中使用的每个数据库:

选项 Joppa 的操作
复制项目的数据库(默认) 以项目的数据库为基础创建 myproject_feature_login_ui:PostgreSQL 使用 TEMPLATE(瞬间完成),否则通过 dump 复制(正被运行中的服务器使用的 PostgreSQL、MySQL、MariaDB)
空数据库 创建一个空数据库;对于 Laravel,如果在准备过程中安装了依赖,会运行 php artisan migrate
使用项目的数据库 worktree 与项目使用同一个数据库

worktree 的 .env 会写入其数据库的名称。Redis、Valkey、Mailpit 和搜索引擎与项目共用。

SQLite 数据库(DB_CONNECTION=sqlite 的 Laravel,或 file: 形式的 DATABASE_URL,包括 Prisma 的)遵循同样的选择:复制该文件、创建一个空文件(若依赖已安装,Laravel 随后会运行迁移),或让 worktree 的 .env 指向项目的文件。git 会忽略这些文件:否则 worktree 将没有数据库。

进程

worktree 的 进程 与项目相同,但使用它自己的端口,Laravel worker 也包括在内:Reverb 通过 REVERB_SERVER_PORT 获得端口,复制过来的 .env 中的 REVERB_PORT 也随之更新。当 Laravel 队列经由 Redis 时(Horizon,或 QUEUE_CONNECTION=redis),worktree 的 php artisan 进程会获得自己的 REDIS_PREFIX 和 HORIZON_PREFIX(myproject_database_feature_login_ui_):它的 worker 绝不会取走项目的 job。Xdebug 沿用项目的设置。它们保存在 Joppa 的配置中,而不是 joppa.toml 中。保存项目的进程时,其 worktree 的进程会随之更新(新进程会获得自己的端口);从 myproject 更新 可随时手动执行。

它的开发服务器在 15 分钟没有请求后会进入休眠,并在下一个请求时被唤醒:几十个 worktree 可以同时保持打开,而不必各自把服务器常驻内存。

准备 worktree

在 Worktree 标签页中,对「未准备」的 worktree 点击 准备。选择它的数据库,然后按需勾选:

  • 安装依赖:没有 node_modules 时运行 bun install(或项目的包管理器),没有 vendor 时运行 composer install;
  • 启动进程:准备就绪后启动。

准备过程的日志会显示出来;打开 进入该环境。

创建 worktree

新建 worktree 会执行 git worktree add,然后准备环境:

  • 新分支(基于当前提交或另一个分支),或 已有分支;
  • 文件夹创建在仓库旁边:myproject-worktrees/<分支>。

在别处创建的 worktree

开启 自动准备新的 worktree(默认开启)后,Joppa 每 3 秒检查一次项目的 worktree,并准备 git、Claude Code、Conductor 或其他智能体刚创建的 worktree:域名、端口、.env 和数据库,数据库按 新 worktree 的数据库 的选择处理。不会安装或启动任何东西:通常由创建 worktree 的工具负责。系统通知会告诉你环境已就绪,并附有 打开。这两项设置可以在 joppa.toml 的 [worktrees] 部分与团队共享。

只有开启之后创建的 worktree 才会被自动准备:之前已存在的需要点击 准备。

worktree 的环境

它显示在侧边栏中其项目的下方,标有 ⎇,并以分支命名。它的页面与项目页面相同(域名、进程、.env、运行时、分析),顶部会提示所属分支,并提供:

  • 打开 myproject;
  • 从 myproject 更新;
  • 删除…:它的域名将被移除,进程将停止。按需勾选 删除它的数据库(为它创建的数据库)和 删除 worktree 文件夹(git worktree remove;如果有未提交的更改会被拒绝,除非勾选 即使有未提交的更改)。

如果你保留文件夹,Joppa 不会再自动准备它(「已忽略」);点击 准备 可重新接管。

getjoppa.com › support

加载中

发送不了?请写信至 [email protected]。只是简单的问题:[email protected]。