WP-CLI#
Every feature is available as wp bb-migrate <command>. The commands are registered after WordPress has loaded, so
they need a working install with the plugin active.
| Command | Purpose |
|---|---|
export |
Export the database to a .sql.gz file |
import |
Import a .sql or .sql.gz file, replacing this site's tables |
replace |
Serialized-safe find and replace in this database |
pull |
Pull a remote site's database into this one |
push |
Push this database to a remote site |
files |
Copy media, theme or plugin files to or from a remote site |
pages |
Page packages: export, import, push, pull, list |
site |
Act on a remote site: plugins, BB Cache, snippet files |
meta |
Copy meta keys of one post to the same post on a remote |
sync |
Whole-site sync: database, then files |
key |
Show or regenerate this site's connection info |
settings |
Show or set the three remote access switches |
Conventions#
Connection. <connection> is the remote's connection string, "<url> <key>", quoted so the shell passes it as
one argument:
wp bb-migrate pull "https://staging.example.com/wp-json/bb-migrate/v1 <key>"
In a script, keep it in a variable or a file that is not committed:
C="$(cat ~/.config/bb-migrate/staging.txt)"
wp bb-migrate files push "$C" --scope=theme:my-theme --dry-run
Replacement pairs. <pairs> is "from=>to", with several pairs separated by ||:
--replace="https://example.com=>https://staging.example.com||/var/www/example/=>/var/www/staging/"
Lists. <list> is comma-separated, without spaces.
Confirmation. Commands that overwrite or delete ask first. --yes answers the prompt. Flags that turn a default
step off are named --skip-… because WP-CLI reserves the --no- prefix.
Exit status. A failed job ends with Error: <message> and a non-zero exit status.
export#
Export the database to a .sql.gz file.
wp bb-migrate export [--file=<path>] [--tables=<list>] [--all-tables] [--replace=<pairs>] [--prefix=<prefix>]
[--exclude-transients] [--exclude-spam] [--exclude-revisions]
| Flag | Meaning |
|---|---|
--file=<path> |
Output path. Default: a new file in uploads/bb-migrate/ named <host>-export-<date>-<random>.sql.gz. A path that does not end in .gz is written uncompressed |
--tables=<list> |
Comma-separated tables. Default: all tables with this site's prefix |
--all-tables |
Include tables without the prefix |
--replace=<pairs> |
Applied to every string while exporting |
--prefix=<prefix> |
Rename the table prefix in the file |
--exclude-transients |
Skip _transient_ rows in the options table |
--exclude-spam |
Skip spam comments |
--exclude-revisions |
Skip post revisions |
wp bb-migrate export --file=/tmp/example.sql.gz --exclude-transients --exclude-spam
See Database: export.
import#
Import a .sql or .sql.gz file, replacing this site's tables.
wp bb-migrate import <file> [--replace=<pairs>] [--skip-backup] [--skip-preserve] [--yes]
| Argument or flag | Meaning |
|---|---|
<file> |
Path to the file |
--replace=<pairs> |
Applied after the import. Default: automatic, from the file's BB Migrate header |
--skip-backup |
Do not export a backup of the current database first |
--skip-preserve |
Do not keep this site's active plugins and BB settings (its BB Migrate settings are kept regardless) |
--yes |
Skip the confirmation. Required when this site is not local |
wp bb-migrate import /tmp/example.sql.gz --yes
See Database: import.
replace#
Serialized-safe find and replace in this database.
wp bb-migrate replace --replace=<pairs> [--tables=<list>] [--dry-run] [--case-insensitive]
| Flag | Meaning |
|---|---|
--replace=<pairs> |
Required |
--tables=<list> |
Comma-separated table names. Default: all tables with this site's prefix |
--dry-run |
Report what would change without writing |
--case-insensitive |
Match case-insensitively |
wp bb-migrate replace --replace="http://example.com=>https://example.com" --dry-run
Ends with Changed <n> rows. or Would change <n> rows. See Database: find and replace.
pull#
Pull a remote site's database into this one. The remote needs allow_pull.
wp bb-migrate pull "<connection>" [--replace=<pairs>] [--tables=<list>] [--exclude-transients] [--exclude-spam]
[--exclude-revisions] [--skip-backup] [--skip-preserve] [--yes]
| Argument or flag | Meaning |
|---|---|
<connection> |
"<url> <key>" from the remote's BB Migrate settings |
--replace=<pairs> |
Default: automatic (remote URL and paths → this site) |
--tables=<list> |
Comma-separated table names, as they are named on the remote |
--exclude-transients |
Skip _transient_ rows in the options table |
--exclude-spam |
Skip spam comments |
--exclude-revisions |
Skip post revisions |
--skip-backup |
Do not export a backup of this site's database first |
--skip-preserve |
Do not keep this site's active plugins and BB settings |
--yes |
Skip the confirmation prompt. Required when this site is not local |
wp bb-migrate pull "https://staging.example.com/wp-json/bb-migrate/v1 <key>" --exclude-transients
push#
Push this database to a remote site. The remote needs allow_push.
wp bb-migrate push "<connection>" [--replace=<pairs>] [--tables=<list>] [--exclude-transients] [--exclude-spam]
[--exclude-revisions] [--skip-backup] [--skip-preserve] [--yes]
| Argument or flag | Meaning |
|---|---|
<connection> |
"<url> <key>" |
--replace=<pairs> |
Default: automatic (this site's URL and paths → remote), applied on the remote |
--tables=<list> |
Comma-separated table names |
--exclude-transients |
Skip _transient_ rows in the options table |
--exclude-spam |
Skip spam comments |
--exclude-revisions |
Skip post revisions |
--skip-backup |
The remote does not back up its database first |
--skip-preserve |
The remote takes this site's active plugins and BB settings, within the limits the remote enforces |
--yes |
Skip the confirmation prompt |
wp bb-migrate push "https://staging.example.com/wp-json/bb-migrate/v1 <key>" --exclude-revisions --yes
files#
Copy media, theme or plugin files to or from a remote site.
wp bb-migrate files <pull|push> "<connection>" [--scope=<scope>] [--paths=<list>] [--paths-file=<file>]
[--delete] [--purge] [--dry-run] [--yes]
| Argument or flag | Meaning |
|---|---|
<direction> |
pull or push |
<connection> |
"<url> <key>" |
--scope=<scope> |
uploads (default), themes, theme:<slug>, plugins, plugin:<slug> |
--paths=<list> |
Only these paths inside the scope, comma-separated: folders, files or globs |
--paths-file=<file> |
The same, one per line. - reads standard input |
--delete |
Also delete files on the destination that the source no longer has (themes and plugins, or uploads with --paths) |
--purge |
Purge the destination's BB Cache afterwards |
--dry-run |
Report what would change without writing |
--yes |
Skip the confirmation that --delete asks for |
wp bb-migrate files push "<connection>" --scope=theme:my-theme --delete --purge --dry-run
wp bb-migrate files push "<connection>" --scope=plugin:bb-cache
wp bb-migrate files push "<connection>" --scope=uploads --paths=2026/10/poster.jpg
wp bb-migrate files pull "<connection>" --scope=uploads --paths=2026
A dry run prints copy <path> and delete <path> lines. The remote needs allow_pull (the file listing),
allow_push for a push, and allow_code_files for theme and plugin scopes. See Files.
pages#
Page packages: selected posts with meta, terms and every referenced attachment.
wp bb-migrate pages export <id|slug|url>… [--file=<path>] [--related] [--with-sizes]
wp bb-migrate pages import <zip> [--status=<status>] [--on-exists=<mode>] [--regenerate]
wp bb-migrate pages push "<connection>" <id|slug|url>… [--status=<status>] [--on-exists=<mode>] [--related]
[--with-sizes] [--regenerate] [--yes]
wp bb-migrate pages pull "<connection>" <id|slug|url>… [--status=<status>] [--on-exists=<mode>] [--related]
[--with-sizes] [--regenerate]
wp bb-migrate pages list "<connection>" [--search=<term>] [--type=<post_type>]
| Argument or flag | Meaning |
|---|---|
<action> |
export (to a zip here), import (a zip here), push (to a remote), pull (from a remote), list (remote posts) |
<args>… |
For push, pull and list the connection string comes first, then post IDs, slugs or URLs. For export: IDs, slugs or URLs. For import: the zip path |
--file=<path> |
export: write the zip here instead of uploads/bb-migrate |
--status=<status> |
private (default), draft, or keep (the source status; publishes if the source was published) |
--on-exists=<mode> |
When a post with the same slug and type exists: new (default: create alongside, WordPress appends -2), update (overwrite its content and meta), skip |
--related |
Also package posts referenced by relationship and post object fields |
--with-sizes |
Transfer the generated image sizes too instead of regenerating them on the destination |
--regenerate |
Rebuild image sizes on the destination even when they arrived |
--search=<term> |
list: filter |
--type=<post_type> |
list: post type (default any) |
--yes |
Skip the confirmation that push --on-exists=update asks for |
An attachment is an item too: by ID, by upload path (2026/10/poster.jpg) or by URL.
wp bb-migrate pages export about-us 1523 --file=/tmp/pages.zip
wp bb-migrate pages import /tmp/pages.zip --status=private
wp bb-migrate pages push "https://staging.example.com/wp-json/bb-migrate/v1 <key>" about-us --on-exists=update --status=draft
wp bb-migrate pages pull "<connection>" https://staging.example.com/company/careers/
wp bb-migrate pages list "<connection>" --search=about --type=page
push, pull and import end with a table of action, from, to, slug and url per post. list prints
ID, type, status, slug, title and modified. See Page packages.
site#
Act on a remote site: plugins, BB Cache, Custom CSS & JS snippet files. The remote needs allow_push; plugin changes
need allow_code_files too.
wp bb-migrate site <action> "<connection>" [<args>…] [--yes]
| Action | Arguments | What it does |
|---|---|---|
plugins |
none | List the remote's plugins |
activate |
plugin slugs | Activate plugins on the remote |
deactivate |
plugin slugs | Deactivate plugins on the remote |
cache |
none | Show the remote's BB Cache settings |
cache-set |
key=value pairs |
Set BB Cache settings on the remote |
cache-copy |
optional key=value pairs |
This site's BB Cache settings → remote, minus the site-specific keys; pairs override |
purge |
none | Purge the remote's cache |
snippets |
optional snippet IDs | Rewrite snippet files from the remote's database |
| Flag | Meaning |
|---|---|
--yes |
Skip the confirmation that activate and deactivate ask for |
wp bb-migrate site plugins "<connection>"
wp bb-migrate site deactivate "<connection>" some-cache-plugin another-plugin
wp bb-migrate site activate "<connection>" bb-cache
wp bb-migrate site cache-copy "<connection>" varnish_host=127.0.0.1
wp bb-migrate site snippets "<connection>"
See Site actions.
meta#
Copy meta keys from a local post to the same post (by slug and type) on a remote: one field, without re-sending the
page. The remote needs allow_push.
wp bb-migrate meta push "<connection>" <post> <keys>… [--type=<post_type>] [--yes]
| Argument or flag | Meaning |
|---|---|
<action> |
push |
<connection> |
"<url> <key>" |
<post> |
Local post ID, slug or URL |
<keys>… |
Meta keys, for example components_4_video_poster |
--type=<post_type> |
Post type for the slug match on the remote. Default: the local post's type |
--yes |
Skip the confirmation |
wp bb-migrate meta push "<connection>" home components_4_video_poster
ACF references travel too, and image, file and gallery values are rewritten through the attachment's upload path.
Push the file first: wp bb-migrate pages push "<connection>" 2026/10/poster.jpg. See
Site actions: meta.
sync#
Whole-site sync: database, then media, themes and plugins.
wp bb-migrate sync <pull|push> "<connection>" [--skip-db] [--files=<list>] [--replace=<pairs>] [--tables=<list>]
[--exclude-transients] [--exclude-spam] [--exclude-revisions] [--skip-backup] [--yes]
| Argument or flag | Meaning |
|---|---|
<direction> |
pull or push |
<connection> |
"<url> <key>" |
--skip-db |
Files only |
--files=<list> |
Comma-separated scopes. Default: uploads,themes,plugins. An empty string means none |
--replace=<pairs> |
Database find and replace. Default: automatic |
--tables=<list> |
Comma-separated table names |
--exclude-transients |
Skip _transient_ rows in the options table |
--exclude-spam |
Skip spam comments |
--exclude-revisions |
Skip post revisions |
--skip-backup |
Do not back up the destination database first |
--yes |
Skip the confirmation prompt |
wp bb-migrate sync pull "<connection>" --yes
wp bb-migrate sync push "<connection>" --files=uploads --exclude-transients
wp bb-migrate sync push "<connection>" --skip-db --files=theme:my-theme
sync runs pull or push and then files once per scope, with no --paths, --delete or --purge. With the
default scopes the remote needs allow_code_files, and allow_pull in both directions.
key#
Show, or regenerate, this site's connection info.
wp bb-migrate key [--regenerate]
| Flag | Meaning |
|---|---|
--regenerate |
Generate a new key first. Existing connection strings for this site stop working |
wp bb-migrate key
# https://example.com/wp-json/bb-migrate/v1 <key>
The output is a credential. Do not paste it into tickets, chat or commit messages.
settings#
Toggle remote access.
wp bb-migrate settings [--allow-pull=<0|1>] [--allow-push=<0|1>] [--allow-code-files=<0|1>]
| Flag | Meaning |
|---|---|
--allow-pull=<n> |
1 allows other sites to pull, 0 stops it |
--allow-push=<n> |
1 accepts pushes, 0 stops them |
--allow-code-files=<n> |
1 allows theme and plugin file transfers, 0 stops them |
With or without flags it prints the current values:
wp bb-migrate settings --allow-push=1 --allow-code-files=1
# allow_pull=0 allow_push=1 allow_code_files=1 verify_ssl=1 max_request=1048576 chunk_rows=500
verify_ssl, max_request, chunk_rows, the retention period and saved connections are set on the Settings tab.