Skip to content

Apply worktree prefix in monorepo default mode#270

Open
DreadPirateJohn wants to merge 1 commit intovercel-labs:mainfrom
DreadPirateJohn:fix/multi-worktree-prefix
Open

Apply worktree prefix in monorepo default mode#270
DreadPirateJohn wants to merge 1 commit intovercel-labs:mainfrom
DreadPirateJohn:fix/multi-worktree-prefix

Conversation

@DreadPirateJohn
Copy link
Copy Markdown

Summary

Bare portless from a workspace root assigns the same hostnames in every git worktree, causing route collisions. portless run --name <name> works correctly. Only the bare-binary monorepo path is affected.

Reproduction

# main checkout
cd ~/repo && portless
# -> https://app.localhost
# -> https://api.localhost

# linked worktree on branch "feature-x"
cd ~/repo/.worktrees/feature-x && portless
# -> https://app.localhost      (collides with main)
# -> https://api.localhost      (collides with main)
#
# expected:
# -> https://feature-x.app.localhost
# -> https://feature-x.api.localhost

Same behavior with or without a portless.json apps map. Reproduced on 0.11.1 and against current main.

Root cause

In packages/portless/src/cli.ts:

  • handleDefaultSingle calls detectWorktreePrefix(cwd) and prepends worktree.prefix to the resolved name.
  • handleDefaultMulti never calls detectWorktreePrefix. The name is taken straight from appOverride.name or ${pkgLabel}.${projectName} with no prefix.

The README's "Git Worktrees" section and the name config field doc ("Worktree prefix still applies") both suggest the prefix should apply in either path.

Fix

Mirror what handleDefaultSingle already does. Detect the worktree once at the top of handleDefaultMulti, then in both branches that compute name extract the existing logic into a baseName local and prepend the prefix when a worktree is detected.

No behavior change in the main checkout: detectWorktreePrefix returns null, the ternary falls through to baseName, and the assigned name is byte-identical to the previous output.

Verification

  • pnpm install, pnpm type-check, pnpm lint, pnpm build, pnpm test all green (595/595 tests pass).
  • Patched against an in-the-wild pnpm monorepo with two apps: main checkout produces <app>.<project>.localhost, linked worktree on branch test-portless produces test-portless.<app>.<project>.localhost as expected.

Happy to add a regression test if there's a preferred fixture pattern for handleDefaultMulti (the existing CLI tests cover the surface but I did not see one specifically exercising the multi + worktree combination).

handleDefaultSingle prepends the git worktree prefix to the resolved
hostname so each linked worktree gets a unique URL. handleDefaultMulti
did not, so bare `portless` from a workspace root produced identical
hostnames across worktrees and routes collided.

Mirror the single-package behavior: detect the worktree once at the top
of handleDefaultMulti and prepend the prefix to both the appOverride.name
branch and the inferred-name branch.

No behavior change in the main checkout (detectWorktreePrefix returns
null and the ternary falls through to the existing baseName).
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 30, 2026

@DreadPirateJohn is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant