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.
composer require woda/laravel-worktreesPublish the config (optional):
php artisan vendor:publish --tag=worktrees-config// 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'),
],
];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 modeOptions: --branch, --base, --issue, --pr, --skip-deps, --skip-build, --skip-db
php artisan worktree:list
php artisan worktree:list --jsonphp 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 databaseRemove stale worktrees.
php artisan worktree:cleanup --dry-run
php artisan worktree:cleanup --forceOpen a worktree in your IDE.
php artisan worktree:open my-featureThe 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.
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=5200Port replacement only applies when the key already exists in your .env file — it won't inject ports you haven't defined.
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);- PHP 8.2+
- Laravel 11 or 12
MIT