Skip to content

CLI Reference ​

Complete command line reference for php-sync-tool.

Commands ​

CommandPurpose
syncSynchronize, the default when no command is named
pull <environment>That environment's database into this project
push <environment>This project's database into that environment
initAsk a few questions and write .sync-tool/ for this project
environmentsList the synchronizations this project is configured for

pull, push, init and environments are described under Named Environments. Every option in this reference applies to pull and push as well, apart from the ORIGIN and TARGET arguments, which the environment name replaces.

Basic Usage ​

bash
bin/sync-tool [OPTIONS] [ORIGIN] [TARGET]

Called with no arguments on a terminal, the tool offers every sync it can find and runs the one you pick. Without a terminal it reports that configuration is missing, exactly as before.

Arguments ​

ArgumentDescription
ORIGINOrigin host name from the host file
TARGETTarget host name from the host file

Both are optional. When omitted, configuration comes from -f or discovery.

Configuration Options ​

OptionShortDescription
--config-file-fPath to a configuration file
--host-file-oAdditional hosts file to merge
--type-tFramework: TYPO3, Symfony, Drupal, WordPress, Laravel

Output & Logging Options ​

OptionShortDescription
--outputOutput mode: interactive, ci, json, quiet (default: interactive)
--mute-mMute console output
--log-file-lWrite log output to a file
--json-logFormat log output as JSON lines
--check-for-updatesCheck Packagist for a newer release, once, at the start of the run

Update Notices ​

Opt-in, on every run it is passed on: a single request to the public Packagist API, with a 2-second timeout. A network failure, a timeout, or no newer release available all look the same — nothing is printed, and the sync is never blocked or delayed beyond that timeout. Only shown in interactive mode; --output ci, --output json and --quiet/--mute never make the request at all. Persist the opt-in in the config file instead of passing the flag on every invocation:

yaml
check_for_updates: true

Progress Display ​

In interactive mode a single live line on stderr tracks the whole run, so piped stdout stays clean. The bar counts the planned steps: the dump, the dump transfer, the import, an after_dump import, the post_sql block and each files entry. The running phase and the rsync percentage appear as fields on the same line, and log lines are printed above it.

The rsync percentage needs --info=progress2, which rsync added in 3.1. On an older rsync (macOS still ships 2.6.9) the transfer runs without it, and the SFTP fallback (--no-rsync) reports no percentage either. In both cases the step count still advances.

The line stays on screen when the run ends and becomes the result: the leading spinner turns into a status icon, the bar fills, and the label reports the outcome. Above it sits a heading naming the tool and both endpoints. Together they are the whole default output of a successful run:

php-sync-tool  remote (www1) ➔ local
✔  Synchronization complete  ██████████████████  100%  4/4  (0:07)

Nothing else is printed, and there is no separate success block on top of the line. --output ci, --output json, --quiet and --mute switch the live line off entirely; without a TTY it degrades to plain log lines and the confirmation is printed as one plain line instead. A failure keeps its own error block, because an error is worth interrupting for.

Add -v for what the tool is doing and -vv for the commands it runs; both are printed above the live line. -v also reports the database version each endpoint runs and how many tables the dump ended up carrying, counted in the dump itself, so it reflects what tables, ignore_table and where let through. -v also names the sync mode on the heading:

php-sync-tool  RECEIVER  remote (www1) ➔ local

Only the mode label appears there, not its (REMOTE ➔ LOCAL) description: the two endpoints on the same line already state the direction. --output ci and --output json report the full mode string, since a log consumer has no line to read it off.

The verbosity threshold applies to interactive only: --output ci and --output json have no live line and keep emitting every message, and the --log-file always records everything.

Execution Options ​

OptionShortDescription
--yes-ySkip the import confirmation prompt
--dry-runResolve and report without export, transfer, or import
--reverse-rSwap origin and target
--force-passwordForce interactive password authentication

Database Dump Options ​

OptionShortDescription
--import-file-iImport from an existing dump file
--dump-nameCustom dump file name
--keep-dumpKeep the dump and skip the import
--clear-databaseDrop all tables before import
--tablesComma-separated list of tables to sync
--whereWHERE clause for mysqldump
--additional-dump-optionsExtra options for the dump binary
--backup-before-importDump the target database before it is overwritten
--no-check-dumpImport without checking the dump is complete (present, intact, fully written)
--target-after-dumpAdditional dump to import on the target after the main import

Legacy dump flags from db-sync-tool ​

-dn <name> and -kd [<dir>] are accepted for db-sync-tool compatibility. They are rewritten before the options are parsed, not registered as regular Symfony Console shortcuts:

  • -dn <name> becomes --dump-name <name>.
  • -kd alone becomes --keep-dump. -kd <dir> becomes --keep-dump --target-dump-dir <dir>, db-sync-tool's -kd having combined "keep the dump" with "put it here". The directory is only consumed when the next token does not itself look like an option.

Transfer Options ​

OptionShortDescription
--no-rsyncDisable rsync and use the SFTP fallback (a local-to-local dump is copied instead)
--use-rsyncNo-op, kept for db-sync-tool compatibility: rsync is already enabled by default
--use-rsync-optionsAdditional rsync options

File Transfer Options ​

OptionShortDescription
--with-filesEnable file synchronization alongside the database
--files-onlySynchronize only files, skip the database
--files-targetTarget path of the first files entry, overriding the configuration

Origin Endpoint Overrides ​

Override individual origin settings from the CLI (no short forms):

OptionDescription
--origin-pathPath to the framework credential file
--origin-nameInformative name for the origin
--origin-hostSSH host
--origin-userSSH user
--origin-passwordSSH password
--origin-keyPath to the SSH private key
--origin-portSSH port
--origin-dump-dirDirectory for the dump file
--origin-keep-dumpsDump retention count
--origin-db-nameDatabase name
--origin-db-hostDatabase host
--origin-db-userDatabase user
--origin-db-passwordDatabase password
--origin-db-portDatabase port

Target Endpoint Overrides ​

The same set of overrides is available for the target:

OptionDescription
--target-pathPath to the framework credential file
--target-nameInformative name for the target
--target-hostSSH host
--target-userSSH user
--target-passwordSSH password
--target-keyPath to the SSH private key
--target-portSSH port
--target-dump-dirDirectory for the dump file
--target-keep-dumpsDump retention count
--target-db-nameDatabase name
--target-db-hostDatabase host
--target-db-userDatabase user
--target-db-passwordDatabase password
--target-db-portDatabase port

Standard Options ​

php-sync-tool is built on Symfony Console, which also provides the standard global options --help (-h), --quiet (-q), --verbose (-v/-vv/-vvv), --version (-V), and --no-interaction (-n).

Named Environments ​

bash
bin/sync-tool init                 # set the project up
bin/sync-tool init -e staging      # add another environment to it
bin/sync-tool environments         # list what is configured
bin/sync-tool pull production      # production → this project
bin/sync-tool push staging         # this project → staging

An environment is a host from hosts.yaml or a file in .sync-tool/. The other side comes from the local block in .sync-tool/defaults.yaml. See Configuration.

init options:

OptionShortDescription
--environment-eName of the environment to set up (default: production)
--forceOverwrite existing files without asking

Run in a project that already carries a defaults.yaml, init keeps it and only adds the environment: the framework and this machine are asked about once, not again for every environment. --force rewrites the defaults from fresh answers.

init needs a terminal; it refuses to run without one rather than writing files from defaults. environments needs none, which is what makes it usable from a script or a Makefile.

Examples ​

Basic Sync with a Config File ​

bash
bin/sync-tool -f config.yaml

Named-Host Sync ​

bash
bin/sync-tool production local

Dry Run ​

bash
bin/sync-tool -f config.yaml --dry-run

Skip Confirmation ​

bash
bin/sync-tool -f config.yaml -y

Import from a Dump File ​

bash
bin/sync-tool -f config.yaml -i /path/to/dump.sql.gz

Keep the Dump Without Importing ​

bash
bin/sync-tool -f config.yaml --keep-dump

Sync Specific Tables ​

bash
bin/sync-tool -f config.yaml --tables=users,orders

Partial Sync with a WHERE Clause ​

bash
bin/sync-tool -f config.yaml --tables=orders --where="created_at > '2024-01-01'"

Clear the Database Before Import ​

bash
bin/sync-tool -f config.yaml --clear-database

Sync Database and Files ​

bash
bin/sync-tool -f config.yaml --with-files

Files Only ​

bash
bin/sync-tool -f config.yaml --files-only

Force SFTP (No rsync) ​

bash
bin/sync-tool -f config.yaml --no-rsync

CI Mode (No Prompts) ​

bash
bin/sync-tool -f config.yaml -y --output=ci

JSON Logging ​

bash
bin/sync-tool -f config.yaml -l /var/log/sync.log --json-log

Released under the GPL-3.0-or-later License.