Worktree Shield

Find the ports, databases and Docker projects your worktrees share

Git worktrees give every agent its own checkout, not its own infrastructure. Worktree Shield audits the worktrees you already have, however they were made, and shows each shared resource with the file and line it comes from.

uv tool install worktree-shield

The example repository: three worktrees made from one branch.

The worktrees as transit lines
What each worktree uses
WorktreePortDatabaseCompose project

What it finds

Each shared resource is a finding with a stable code, the evidence for every worktree, and how certain the collision is. worktree-shield explain CODE tells you more about one.

  • Listen portsWTS-PORT-001

    Dev servers on the same port: only one can listen at a time. With a process already holding it, WTS-PORT-002 confirms it.

  • DatabasesWTS-DB-001

    The same database on the same server: one worktree’s migrations and seed data change the other’s.

  • Compose projectsWTS-DOCKER-001

    One project name: docker compose up in one worktree takes over the other’s containers.

  • Container names and volumesWTS-DOCKER-002/003

    Fixed container_name values and named volumes that every stack mounts.

  • Absolute pathsWTS-PATH-001

    Upload, cache and output folders outside the worktree that each one writes to.

Read from .env.example (and .env when you opt in), package.json scripts, Vite configs, pyproject.toml tasks, Compose files, Procfiles and dev containers, and the ports running processes listen on. Everything that is read.

It says how sure it is

Two worktrees that configure the same port will collide only if both servers run. So a finding from configuration is probable; it becomes confirmed when a running process, found by its working directory, already holds the port. Ports that only might overlap, such as a wildcard and a specific address, are possible.

Sharing on purpose is fine: allow one Postgres for everyone in .worktree-shield.toml, and --strict fails only on what your policy denies.

confirmed
A process from another worktree listens on the port right now.
probable
The configuration of two worktrees names the same resource.
possible
The resources may overlap; it depends on how they are reached.

The scan, as your terminal shows it

The example repository has three worktrees that start a server on 5173, use the database app_dev and share one Compose project. Every line of evidence names the worktree, the file and the line.

worktree-shield scan            # all worktrees, read-only
worktree-shield scan --strict   # exit 1 when a finding fails
worktree-shield plan            # one change per worktree; never applied
worktree-shield resources       # every resource each worktree declares
worktree-shield report -f sarif -o conflicts.sarif

Try it on a repository built to collide: python examples/conflicting-worktrees/build.py /tmp/wts-demo.

worktree-shield scan on three worktrees: FAIL WTS-PORT-001 for port 5173 configured in three worktrees, WARN WTS-DB-001 for the database app_dev and WARN WTS-DOCKER-001 for the Compose project app, each with the file and line in every worktree and the next step.

In CI and before an agent starts

A CI checkout is a single worktree, so the GitHub Action checks your branch out next to another ref and reports what the two would share, as SARIF for code scanning. On your machine, scan --strict --format json is a preflight an agent can run before it starts a server.

In CI the scan is static: the processes on a runner say nothing about your machine.

- uses: actions/checkout@v7
- uses: BhuwanJoshi-01/worktree-shield@v0.1.0
  with:
    compare-with: main
    strict: "true"
- uses: github/codeql-action/upload-sarif@v4
  if: always()
  with:
    sarif_file: worktree-shield.sarif

What it never does

  • Run your code. Package scripts, Git hooks, Vite configs and Compose are parsed as data, never executed. Docker doesn’t need to be running.
  • Change anything. No writes to your worktrees or .git, no locks, no pruning, no killed processes, no touched databases.
  • Print secrets. Database URLs are cut to host, port and name as they are read; .env files are read only when you opt in.
  • Phone home. No network access, no telemetry.

Creating worktrees with their own ports instead? workz and worktree-compose do that. Worktree Shield creates nothing; it audits whatever is already there.