Skip to content

feat: add git worktree isolation via port shifting#421

Open
bastnic wants to merge 1 commit into
mainfrom
feat/git-worktree-support
Open

feat: add git worktree isolation via port shifting#421
bastnic wants to merge 1 commit into
mainfrom
feat/git-worktree-support

Conversation

@bastnic

@bastnic bastnic commented Jul 15, 2026

Copy link
Copy Markdown
Member

Summary

When using git worktrees (e.g. with an AI coding agent working on multiple branches), each worktree needs its own isolated Docker infrastructure — otherwise containers, volumes, networks, and ports conflict.

This PR adds automatic detection of git worktrees and shifts Docker Compose project names and ports accordingly, so each worktree runs its own stack in parallel without modifying /etc/hosts.

How it works

  • Detection: parses the .git file (content: gitdir: ...) to detect worktree mode
  • Project name: suffixed with -wt-<worktree-name> → Docker Compose isolates containers, volumes, networks automatically
  • Ports: derived from a CRC32 hash of the worktree name (range 10000-60000) to avoid collisions
  • Domains: kept unchanged — no /etc/hosts modifications per worktree

UX

  • castor start now prints the allocated ports at the end
  • castor about includes the HTTPS port in URLs when in a worktree
  • New castor docker:ports task to display ports at any time
  • Outside worktrees: behavior is identical to before (default ports 80/443/8080)
$ castor about

[...]

Available URLs for this project:
--------------------------------

 * https://app.test:30411
 * https://www.app.test:30411

$ castor docker:ports

Ports
=====

 --------------- ------------------------------------
  Worktree        worktree-silver-harbor-5d67
  Project         app-wt-worktree-silver-harbor-5d67
  HTTP            http://app.test:30410
  HTTPS           https://app.test:30411
  Traefik admin   http://localhost:30412
 --------------- ------------------------------------

@Korbeil Korbeil left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

implementation seems nice !
since the worktree usage is clearly agents focused, I think we should bundle a template AGENTS.md with minimum instruction about this worktree support so agents can use it efficiently

@lyrixx lyrixx left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, but IMHO we could simplify this but not using the context for fews keys

Comment thread .castor/context.php Outdated
Comment thread .castor/context.php
Comment thread .castor/context.php Outdated
Comment thread .castor/worktree.php Outdated
@bastnic bastnic force-pushed the feat/git-worktree-support branch from 4f658da to bd6a9c1 Compare July 16, 2026 10:03

@lyrixx lyrixx left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice ! Except three little comment, I'm 👍🏼

Comment thread .castor/docker.php
$urls = [variable('root_domain'), ...variable('extra_domains')];

$worktreeName = get_worktree_name();
$adminPort = null !== $worktreeName ? get_worktree_ports($worktreeName)['admin'] : null;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So admin port can be null? then the next line will fail :/ could the default value ve 8080? (old defefault one)

Comment thread .castor/docker.php
}

io()->listing(array_map(static fn ($url) => "https://{$url}", array_unique($urls)));
$worktreeName = get_worktree_name();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you already get that var about, L41

Comment thread .castor/context.php
use function worktree\get_worktree_name;

/** @return array<string, array{env: string, default: int, label: string}> */
function get_port_specs(): array

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this function should goes to docker.php, WDYT?

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.

3 participants