Docs
Compare git branches
Turn any branch into a working site, with its own database copy and migrations, and compare it.
Any name in New comparison that isn't a configured environment is treated as a git branch, tag or commit, and visualdiff turns it into a working site:
- A worktree. If one of your checkouts already has the branch, visualdiff uses it. Otherwise it creates a git worktree next to the repo (
../.worktrees/<project>/vdiff-<branch>). - Files. It copies the untracked files the site needs (
.env, licence files) with their hosts rewritten for the branch, and links upload folders. - Its own database. It copies your database (
mysqldump) into<project>_vdiff_<branch>and points the branch's.envat the copy. - Setup and migrations. It runs your setup commands once (
composer install, an asset build), then migrations (craft up,artisan migrate). For WordPress it updateshomeandsiteurlin the copy. - Serving. It serves the branch (see below) and captures it like any other environment.
vdiff compare main feature/craft-4
Why a copy of the database?#
Upgrade branches run migrations. If two branches shared one database, migrating the Craft 4 branch would break the Craft 3 one. Each branch gets its own copy, so they can be compared side by side and neither touches the database you work on.
How branches are served#
| Mode | What visualdiff does | You need |
|---|---|---|
herd |
Links the worktree in Herd as <project>-<branch>.test, plus one link per extra site (-fr, -es) |
Herd |
php |
Runs PHP's built-in server for the worktree while the comparison runs, at http://<project>-<branch>.localhost:84xx/. *.localhost works on every Mac with no setup |
PHP |
manual |
Prepares the worktree and its database; you serve it (DDEV, Docker, Valet, nginx) and give its URL in New comparison | Your server |
auto (default) |
herd when Herd is installed, otherwise php |
Set it in the config: "branches": { "serve": "php" }.
The database works the same in every mode: visualdiff copies it on the MySQL or MariaDB server your .env points at (Herd, DBngin, Homebrew, or a container with its port published). SQLite projects copy the database file. If your database lives somewhere visualdiff can't reach, use "database": { "mode": "shared" } and let your migrate commands handle it, for example "migrate": ["ddev exec php craft up --interactive=0"].
Later runs#
- Each run moves the branch's worktree to its latest commit. Setup runs again if a lockfile changed, and migrations if the code moved.
- Fresh database (checkbox, or
--fresh-db) copies the database again and re-runs migrations, for a clean start. - visualdiff never runs commands in, or edits files of, a checkout it didn't create.
Clean up#
vdiff branch:down feature/craft-4 --drop-db
removes the worktree, the Herd links and the database copy.
Settings#
"branches": {
"serve": "auto", // herd | php | manual | auto
"copy": [".env", "config/license.key"], // untracked files copied into new worktrees
"link": ["web/uploads"], // untracked folders linked
"setup": ["{composer} install --no-interaction", "npm ci", "npm run build"],
"migrate": ["{php} craft up --interactive=0"],
"database": { "mode": "clone" } // clone | shared
}
Commands can use {php}, {composer}, {url}, {host}, {sourceUrl} and {sourceHost}.