Skip to content

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

See Database: push and pull.

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.