Skip to content
ClientSelectorspseudo-classes:diff()

:diff()

The :diff() pseudo-class matches packages whose files have changed between the current working tree and a specified git commitish reference. It uses git diff --name-only to determine changed files, then maps them to packages by their file path location.

Syntax

:diff()
:diff(<commitish>)

When called with no argument, defaults to HEAD (uncommitted changes). Untracked files are not seen — git diff only reports tracked ones.

The comparison is two-dot: the ref’s tree against your working tree, in both directions. To compare against the merge base instead — “what this branch changed”, regardless of how far main has moved — use the three-dot form, :diff(main...HEAD).

Refs containing a / must be quoted, :diff("origin/main"); unquoted, the selector parser rejects the slash.

Examples

Uncommitted changes

Find packages with uncommitted changes:

Terminal
$ vlt query ':diff()'

Changes since a branch

Find packages changed since the main branch:

Terminal
$ vlt query ':diff(main)'

Changes since last commit

Terminal
$ vlt query ':diff(HEAD~1)'

Changes since a tag

Terminal
$ vlt query ':diff("v1.0.0")'

Only workspaces that changed

Terminal
$ vlt query ':workspace:diff(main)'

What gets selected

Given a monorepo where you changed files in packages/core/ and packages/utils/ since main:

my-monorepo
├── packages/core/ ← files changed
├── packages/utils/ ← files changed
├── packages/cli/
└── apps/web/

:diff(main) selects:

my-monorepo
├── packages/core/ ✅ has changed files
├── packages/utils/ ✅ has changed files
├── packages/cli/
└── apps/web/

CI use cases

Run tests only for changed workspaces:

Terminal
$ vlt run test --scope=':workspace:diff(main...HEAD)'

Find packages that depend on changed packages:

Terminal
$ vlt query ':has(:diff(main))'

See also