Mutagen is a fast, continuous, bidirectional file synchronization tool designed to support remote development scenarios.
Mutagen uses a bidirectional version of the rsync algorithm to safely, scalably, and efficiently synchronize filesystem contents between arbitrary pairs of locations in near real-time. Support is currently implemented for locations on local filesystems, SSH-accessible filesystems, and Docker container filesystems. Filesystem contents are monitored for changes at both locations and any non-conflicting changes are propagated automatically.
Mutagen is unique amongst synchronizers in that it does not need to be installed on remote systems, has no dependencies, and runs completely in user space (no pesky kernel extensions required). It also has some nifty safety features to avoid accidental data deletion.
Although it can synchronize any content efficiently, Mutagen is tailored for synchronizing code in remote development scenarios. It handles cross-platform quirks by default, manages conflicts safely, and provides powerful configuration options for handling things like symlinks and ignores in a portable fashion.
Mutagen is also extremely robust to connection dropouts. Since the contents it deals with exist on the actual filesystem, they won't disappear or become unavailable if the connection drops, and they can continue to be accessed and edited offline. As soon as Mutagen can reconnect, it will automatically resume synchronization right where it left off.
Mutagen can manage any number of active synchronization sessions at once. It provides a number of subcommands that allow for the creation and management of sessions, as well as management of Mutagen's daemon component. The following sections outline usage of these commands. Additional usage information is available through the built-in help:
$ mutagen --help
More detailed information about Mutagen's design can be found in the README.
Mutagen can be installed by downloading the appropriate release for your platform and adding its contents to your path.
Alternatively, Homebrew users can install Mutagen with:
$ brew install havoc-io/mutagen/mutagen
There is no need to install Mutagen on remote systems.
Mutagen relies on a daemon that runs in the background as a per-user process and manages synchronization sessions. If a session becomes disconnected from a remote system, the daemon will automatically attempt to reconnect the session in the background.
The Mutagen daemon is started using the
daemon command:
$ mutagen daemon start
This command is fast and idempotent, so it can safely be
added to your shell initialization script
(e.g. .bashrc, etc).
The daemon will automatically stop at shutdown, but you
can also manually stop it using
mutagen daemon stop. Make sure to stop the
daemon before upgrading Mutagen and to restart it
afterwards.
Experimental support for registering the daemon to start
automatically on login is available for macOS and
Windows via the mutagen daemon register
command.
Sessions can be created using the create
command:
$ mutagen create Projects/my_project user@hostname:~/my_project_copy
The create command takes two filesystem location specifications (referred to as "endpoints") and creates a synchronization session between them. The order of the endpoints is not important — it only determines which will be referred to as "alpha" and which will be referred to as "beta". Both endpoints are considered equal and non-conflicting changes propagate bidirectionally between them.
Endpoint specifications can be local paths,
SSH URLs,
or
Docker URLs.
Mutagen uses OpenSSH
under the hood, so all of your settings, keys, and
aliases will be automatically available. If confirmation
or authentication is required to connect to a remote
endpoint, then the create command will
prompt accordingly.
Mutagen can create synchronization sessions between arbitrary pairs of endpoints — one needn't be local. For example, you could set up synchronization between an SSH-accessible filesystem location and a folder inside a Docker container without ever having a copy of the files locally. The Mutagen daemon simply acts as a proxy and arbiter for endpoints.
The create command also supports a number
of
configuration options for
symlinks,
ignores,
and filesystem watching.
The list command shows the current status
of sessions, as well as any conflicts or problems that
have arisen in the propagation of changes between
endpoints:
$ mutagen list
Session: 7bb4a56b-f4be-4083-be24-7f590beda02e
Alpha:
URL: /Users/me/Projects/my_project
Status: Connected
Beta:
URL: user@hostname:~/my_project_copy
Status: Connected
Status: Watching for changes
Each session is assigned a unique identifier that can be
used to refer to it in Mutagen commands. This identifier
will be printed by the create command and
can be seen in the list command's output.
Sessions can also be referred to by a fragment of either
endpoint path or hostname, so long as this specification
is unambiguous.
If no sessions are specified to the list
command, it will simply print all sessions. More
detailed listing output is available through the
-l/--long flag.
The monitor command shows live monitoring
information for a session:
$ mutagen monitor my_project
Session: 7bb4a56b-f4be-4083-be24-7f590beda02e
Alpha: /Users/me/Projects/my_project
Beta: user@hostname:~/my_project_copy
Status: Staging files on beta: 75% (8942/11782)
If no session is specified, monitor will
show information for the most recently created session.
Synchronization can be temporarily halted for a session
using the pause command:
$ mutagen pause my_project
Sessions can be resumed using the resume
command:
$ mutagen resume my_project
This command will ensure that a session is unpaused and
attempting to synchronize. If the daemon can't
automatically reconnect to an endpoint because
confirmation or authentication is required, the
resume command can be used to provide the
necessary input.
Synchronization can be permanently halted for a session
(and the session deleted) using the
terminate command:
$ mutagen terminate my_project
This will not delete files on either endpoint (but should be done before completely deleting files on either endpoint to avoid propagating the deletion).