woda / laravel-worktrees
Git worktree management with database cloning for Laravel
Requires
- php: ^8.2
- illuminate/console: ^11.0 || ^12.0
- illuminate/process: ^11.0 || ^12.0
- illuminate/support: ^11.0 || ^12.0
Requires (Dev)
- driftingly/rector-laravel: ^2.1
- larastan/larastan: ^3.0
- laravel/pint: ^1.0
- orchestra/testbench: ^9.0 || ^10.0
- pestphp/pest: ^3.0 || ^4.0
- pestphp/pest-plugin-laravel: ^3.0 || ^4.0
- phpstan/phpstan: ^2.0
- rector/rector: ^2.0
- systemsdk/phpcpd: ^8.0
This package is auto-updated.
Last update: 2026-03-04 21:28:09 UTC
README
Git worktree management with database cloning for Laravel.
Create isolated development environments from your Laravel project using git worktrees. Each worktree gets its own branch, dependencies, database clone, and frontend build.
Installation
composer require woda/laravel-worktrees
Publish the config (optional):
php artisan vendor:publish --tag=worktrees-config
Configuration
// config/worktrees.php return [ 'base_path' => env('WORKTREE_BASE_PATH', dirname(base_path())), 'branch_prefix' => env('WORKTREE_BRANCH_PREFIX', ''), 'base_branch' => env('WORKTREE_BASE_BRANCH', 'master'), 'copy_files' => ['.env'], 'database' => [ 'strategy' => env('WORKTREE_DB_STRATEGY', 'auto'), // auto|sqlite|mysql|pgsql|none 'sqlite_copy' => true, 'mysql_docker_container' => env('WORKTREE_DB_MYSQL_DOCKER_CONTAINER'), 'pgsql_docker_container' => env('WORKTREE_DB_PGSQL_DOCKER_CONTAINER'), 'docker_host' => env('WORKTREE_DB_DOCKER_HOST', '127.0.0.1'), ], 'ports' => [ 'app_base' => (int) env('WORKTREE_APP_PORT_BASE', 8100), 'vite_base' => (int) env('WORKTREE_VITE_PORT_BASE', 5200), ], 'bootstrap' => [ 'node_package_manager' => env('WORKTREE_NODE_PM', 'pnpm'), 'build_frontend' => true, 'run_migrations' => true, ], 'ide' => [ 'command' => env('WORKTREE_IDE_COMMAND', 'phpstorm'), ], ];
Commands
worktree:create
Create a worktree with full environment isolation.
php artisan worktree:create my-feature php artisan worktree:create --issue=42 # From GitHub issue php artisan worktree:create --pr=10 # From pull request php artisan worktree:create --branch=existing # From existing branch php artisan worktree:create # Interactive mode
Options: --branch, --base, --issue, --pr, --skip-deps, --skip-build, --skip-db
worktree:list
php artisan worktree:list php artisan worktree:list --json
worktree:delete
php artisan worktree:delete my-feature php artisan worktree:delete my-feature --force # Skip safety checks php artisan worktree:delete my-feature --keep-db # Keep cloned database
worktree:cleanup
Remove stale worktrees.
php artisan worktree:cleanup --dry-run php artisan worktree:cleanup --force
worktree:open
Open a worktree in your IDE.
php artisan worktree:open my-feature
Database Strategies
The database.strategy config determines how databases are cloned:
| Strategy | Behavior |
|---|---|
auto |
Detect from database.default config |
sqlite |
Copy the SQLite file into the worktree |
mysql |
mysqldump | mysql into a new database |
pgsql |
pg_dump | psql into a new database |
none |
Skip database cloning |
Docker containers are supported for MySQL and PostgreSQL — set the container name in config and the commands will be wrapped with docker exec.
Port Isolation (Sail)
When running multiple worktrees with Laravel Sail, each worktree needs unique host ports to avoid conflicts. If your .env contains APP_PORT or VITE_PORT, the package will automatically derive unique ports per worktree.
Ports are computed as base + (crc32(name) % 900), giving ranges of 8100–8999 for APP_PORT and 5200–6099 for VITE_PORT by default. Configure the base ports in config/worktrees.php or via environment variables:
WORKTREE_APP_PORT_BASE=8100 WORKTREE_VITE_PORT_BASE=5200
Port replacement only applies when the key already exists in your .env file — it won't inject ports you haven't defined.
ProcessManager Contract
The package binds a NullProcessManager by default. To integrate with a process manager (e.g. screen sessions, tmux), implement Woda\Worktrees\Contracts\ProcessManager:
interface ProcessManager { public function isRunning(string $worktreeName): bool; public function terminate(string $worktreeName): void; public function runningLabel(string $worktreeName): string|null; }
Bind your implementation in a service provider:
$this->app->bind(ProcessManager::class, MyProcessManager::class);
Requirements
- PHP 8.2+
- Laravel 11 or 12
License
MIT