A DDEV addon for creating, managing, and removing independent clones of DDEV projects.
Each clone has its own code copy (via git worktree or directory copy), independent Docker volumes, and a separate DDEV project — enabling parallel development without conflicts.
ddev add-on get civicactions/ddev-cloneFor global installation (available across all projects):
ddev add-on get --global civicactions/ddev-clone# Create a clone of the current project
ddev clone create feature-x
# List all clones
ddev clone list
# Remove a clone
ddev clone remove feature-x
# Clean up stale references
ddev clone pruneCreates a fully independent clone of the current DDEV project:
- Creates a code copy (git worktree or directory copy)
- Copies all Docker volumes (database, config, snapshots)
- Configures a new DDEV project via
config.local.yaml - Starts the clone and makes it accessible
Flags:
| Flag | Description |
|---|---|
-b, --branch <name> |
Check out an existing branch (worktree strategy only) |
--code-strategy <type> |
Code isolation: worktree or copy (default: auto-detect) |
--no-start |
Configure the clone but do not start it |
Examples:
ddev clone create feature-x
ddev clone create feature-x --branch existing-branch
ddev clone create feature-x --code-strategy=copy
ddev clone create feature-x --no-startLists all clones of the current project with name, path, branch, strategy, and status.
Flags:
| Flag | Description |
|---|---|
-j, --json-output |
Output in JSON format |
Removes a clone and cleans up all Docker resources, code copy, and project registration.
Flags:
| Flag | Description |
|---|---|
--force |
Skip confirmation for dirty worktrees/directories |
Cleans up clones whose directories have been manually deleted.
Flags:
| Flag | Description |
|---|---|
--dry-run |
Show what would be pruned without taking action |
Uses git worktree add to create a linked worktree. Clones share git history with the source project, enabling efficient disk usage and easy branch management.
Advantages:
- Disk-efficient (shares git objects)
- Full git history available
- Easy branch switching
Requirements:
- Source directory must be a git repository
gitmust be on PATH
Creates a full recursive copy of the project directory using otiai10/copy with preserved timestamps, ownership, and symlinks.
Advantages:
- Works with any project (git or not)
- Fully independent copy
- No git dependency
Auto-detection: If no --code-strategy is specified and the project is not a git repository, the copy strategy is used automatically.
- Code isolation: Creates a code copy using the selected strategy
- Config override: Writes
.ddev/config.local.yamlwith the clone's project name - Volume duplication: Stops the source DB, copies Docker volumes via tar pipe in Alpine container, restarts source DB
- Project start: Runs
ddev starton the clone (handles container creation, networking, etc.)
| Volume | When |
|---|---|
| Database (MariaDB/MySQL/PostgreSQL) | Always |
| Snapshots | If exists |
| DDEV config | If exists |
| Mutagen sync | If Mutagen is enabled |
| Custom service volumes | If Docker Compose overrides exist |
Pre-pull the Alpine image:
docker pull alpine:latestEnsure DDEV is installed and on your PATH:
which ddev
ddev --versionLarge databases may take several minutes. The addon stops only the DB container during copy to minimize downtime.
If a clone has uncommitted changes, you'll be prompted. Use --force to skip:
ddev clone remove feature-x --forcemake build # Build for current platform
make build-all # Build for all 6 platformsmake test # Run all tests
make coverage # Run tests with coveragemake lint # Run golangci-lint
make fmt # Format code
make vet # Run go vet- DDEV >= 1.24.0
- Docker
- Git (for worktree strategy)
Apache License 2.0. See LICENSE for details.