title: "Bisync" description: "Bidirectional cloud sync solution in rclone" versionIntroduced: "v1.58"
Bisync
bisync is considered an advanced command, so use with care.
Make sure you have read and understood the entire
manual (especially the Limitations
section) before using, or data loss can result. Questions can be asked in the
Rclone Forum.
Getting started {#getting-started}
- Install rclone and setup your remotes.
- Bisync will create its working directory at
~/.cache/rclone/bisyncon Linux,/Users/yourusername/Library/Caches/rclone/bisyncon Mac, orC:\Users\MyLogin\AppData\Local\rclone\bisyncon Windows. Make sure that this location is writable. - Run bisync with the
--resyncflag, specifying the paths to the local and remote sync directory roots. - For successive sync runs, leave off the
--resyncflag. (Important!) - Consider using a filters file for excluding unnecessary files and directories from the sync.
- Consider setting up the --check-access feature for safety.
- On Linux or Mac, consider setting up a crontab entry. bisync can safely run in concurrent cron jobs thanks to lock files it maintains.
For example, your first command might look like this:
rclone bisync remote1:path1 remote2:path2 --create-empty-src-dirs --compare size,modtime,checksum --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync --dry-run
If all looks good, run it again without --dry-run.
After that, remove --resync as well.
Here is a typical run log (with timestamps removed for clarity):
rclone bisync /testdir/path1/ /testdir/path2/ --verbose
INFO : Synching Path1 "/testdir/path1/" with Path2 "/testdir/path2/"
INFO : Path1 checking for diffs
INFO : - Path1 File is new - file11.txt
INFO : - Path1 File is newer - file2.txt
INFO : - Path1 File is newer - file5.txt
INFO : - Path1 File is newer - file7.txt
INFO : - Path1 File was deleted - file4.txt
INFO : - Path1 File was deleted - file6.txt
INFO : - Path1 File was deleted - file8.txt
INFO : Path1: 7 changes: 1 new, 3 newer, 0 older, 3 deleted
INFO : Path2 checking for diffs
INFO : - Path2 File is new - file10.txt
INFO : - Path2 File is newer - file1.txt
INFO : - Path2 File is newer - file5.txt
INFO : - Path2 File is newer - file6.txt
INFO : - Path2 File was deleted - file3.txt
INFO : - Path2 File was deleted - file7.txt
INFO : - Path2 File was deleted - file8.txt
INFO : Path2: 7 changes: 1 new, 3 newer, 0 older, 3 deleted
INFO : Applying changes
INFO : - Path1 Queue copy to Path2 - /testdir/path2/file11.txt
INFO : - Path1 Queue copy to Path2 - /testdir/path2/file2.txt
INFO : - Path2 Queue delete - /testdir/path2/file4.txt
NOTICE: - WARNING New or changed in both paths - file5.txt
NOTICE: - Path1 Renaming Path1 copy - /testdir/path1/file5.txt..path1
NOTICE: - Path1 Queue copy to Path2 - /testdir/path2/file5.txt..path1
NOTICE: - Path2 Renaming Path2 copy - /testdir/path2/file5.txt..path2
NOTICE: - Path2 Queue copy to Path1 - /testdir/path1/file5.txt..path2
INFO : - Path2 Queue copy to Path1 - /testdir/path1/file6.txt
INFO : - Path1 Queue copy to Path2 - /testdir/path2/file7.txt
INFO : - Path2 Queue copy to Path1 - /testdir/path1/file1.txt
INFO : - Path2 Queue copy to Path1 - /testdir/path1/file10.txt
INFO : - Path1 Queue delete - /testdir/path1/file3.txt
INFO : - Path2 Do queued copies to - Path1
INFO : - Path1 Do queued copies to - Path2
INFO : - Do queued deletes on - Path1
INFO : - Do queued deletes on - Path2
INFO : Updating listings
INFO : Validating listings for Path1 "/testdir/path1/" vs Path2 "/testdir/path2/"
INFO : Bisync successful
Command line syntax
$ rclone bisync --help
Usage:
rclone bisync remote1:path1 remote2:path2 [flags]
Positional arguments:
Path1, Path2 Local path, or remote storage with ':' plus optional path.
Type 'rclone listremotes' for list of configured remotes.
Optional Flags:
--backup-dir1 string --backup-dir for Path1. Must be a non-overlapping path on the same remote.
--backup-dir2 string --backup-dir for Path2. Must be a non-overlapping path on the same remote.
--check-access Ensure expected RCLONE_TEST files are found on both Path1 and Path2 filesystems, else abort.
--check-filename string Filename for --check-access (default: RCLONE_TEST)
--check-sync string Controls comparison of final listings: true|false|only (default: true) (default "true")
--compare string Comma-separated list of bisync-specific compare options ex. 'size,modtime,checksum' (default: 'size,modtime')
--conflict-loser ConflictLoserAction Action to take on the loser of a sync conflict (when there is a winner) or on both files (when there is no winner): , num, pathname, delete (default: num)
--conflict-resolve string Automatically resolve conflicts by preferring the version that is: none, path1, path2, newer, older, larger, smaller (default: none) (default "none")
--conflict-suffix string Suffix to use when renaming a --conflict-loser. Can be either one string or two comma-separated strings to assign different suffixes to Path1/Path2. (default: 'conflict')
--create-empty-src-dirs Sync creation and deletion of empty directories. (Not compatible with --remove-empty-dirs)
--download-hash Compute hash by downloading when otherwise unavailable. (warning: may be slow and use lots of data!)
--filters-file string Read filtering patterns from a file
--force Bypass --max-delete safety check and run the sync. Consider using with --verbose
-h, --help help for bisync
--ignore-listing-checksum Do not use checksums for listings (add --ignore-checksum to additionally skip post-copy checksum checks)
--max-lock Duration Consider lock files older than this to be expired (default: 0 (never expire)) (minimum: 2m) (default 0s)
--no-cleanup Retain working files (useful for troubleshooting and testing).
--no-slow-hash Ignore listing checksums only on backends where they are slow
--recover Automatically recover from interruptions without requiring --resync.
--remove-empty-dirs Remove ALL empty directories at the final cleanup step.
--resilient Allow future runs to retry after certain less-serious errors, instead of requiring --resync.
-1, --resync Performs the resync run. Equivalent to --resync-mode path1. Consider using --verbose or --dry-run first.
--resync-mode string During resync, prefer the version that is: path1, path2, newer, older, larger, smaller (default: path1 if --resync, otherwise none for no resync.) (default "none")
--retries int Retry operations this many times if they fail (requires --resilient). (default 3)
--retries-sleep Duration Interval between retrying operations if they fail, e.g. 500ms, 60s, 5m (0 to disable) (default 0s)
--slow-hash-sync-only Ignore slow checksums for listings and deltas, but still consider them during sync calls.
--workdir string Use custom working dir - useful for testing. (default: {WORKDIR})
--max-delete PERCENT Safety check on maximum percentage of deleted files allowed. If exceeded, the bisync run will abort. (default: 50%)
-n, --dry-run Go through the motions - No files are copied/deleted.
-v, --verbose Increases logging verbosity. May be specified more than once for more details.
Arbitrary rclone flags may be specified on the
bisync command line, for example
rclone bisync ./testdir/path1/ gdrive:testdir/path2/ --drive-skip-gdocs -v -v --timeout 10s
Note that interactions of various rclone flags with bisync process flow
has not been fully tested yet.
Paths
Path1 and Path2 arguments may be references to any mix of local directory
paths (absolute or relative), UNC paths (//server/share/path),
Windows drive paths (with a drive letter and :) or configured
remotes with optional subdirectory paths.
Cloud references are distinguished by having a : in the argument
(see Windows support below).
Path1 and Path2 are treated equally, in that neither has priority for file
changes (except during --resync), and access efficiency does not
change whether a remote is on Path1 or Path2.
The listings in bisync working directory (default: ~/.cache/rclone/bisync)
are named based on the Path1 and Path2 arguments so that separate syncs
to individual directories within the tree may be set up, e.g.:
path_to_local_tree..dropbox_subdir.lst.
Any empty directories after the sync on both the Path1 and Path2 filesystems are
not deleted by default, unless --create-empty-src-dirs is specified. If the
--remove-empty-dirs flag is specified, then both paths will have ALL empty
directories purged as the last step in the process.
Command-line flags
--resync
This will effectively make both Path1 and Path2 filesystems contain a matching superset of all files. By default, Path2 files that do not exist in Path1 will be copied to Path1, and the process will then copy the Path1 tree to Path2.
The --resync sequence is roughly equivalent to the following
(but see --resync-mode for other options):
rclone copy Path2 Path1 --ignore-existing [--create-empty-src-dirs]
rclone copy Path1 Path2 [--create-empty-src-dirs]
The base directories on both Path1 and Path2 filesystems must exist or bisync will fail. This is required for safety - that bisync can verify that both paths are valid.
When using --resync, a newer version of a file on the Path2 filesystem
will (by default) be overwritten by the Path1 filesystem version.
(Note that this is NOT entirely symmetrical,
and more symmetrical options can be specified with the
--resync-mode flag.)
Carefully evaluate deltas using --dry-run.
For a resync run, one of the paths may be empty (no files in the path tree). The resync run should result in files on both paths, else a normal non-resync run will fail.
For a non-resync run, either path being empty (no files in the tree) fails with
Empty current PathN listing. Cannot sync to an empty directory: X.pathN.lst
This is a safety check that an unexpected empty path does not result in
deleting everything in the other path.
Note that --resync implies --resync-mode path1 unless a different
--resync-mode is explicitly specified.
It is not necessary to use both the --resync and --resync-mode flags --
either one is sufficient without the other.
Note: --resync (including --resync-mode) should only be used under three
specific (rare) circumstances:
- It is your first bisync run (between these two paths)
- You've just made changes to your bisync settings (such as editing the
contents of your
--filters-file) - There was an error on the prior run, and as a result, bisync now requires
--resyncto recover
The rest of the time, you should omit --resync. The reason is because --resync
will only copy (not sync) each side to the other. Therefore, if you included
--resync for every bisync run, it would never be possible to delete a file -- the
deleted file would always keep reappearing at the end of every run (because it's
being copied from the other side where it still exists). Similarly, renaming a
file would always result in a duplicate copy (both old and new name) on both
sides.
If you find that frequent interruptions from #3 are an issue, rather than
automatically running --resync, the recommended alternative is to use the
--resilient, --recover, and
--conflict-resolve flags, (along with Graceful
Shutdown mode, when needed) for a very robust
"set-it-and-forget-it" bisync setup that can automatically bounce back from
almost any interruption it might encounter. Consider adding something like the
following:
--resilient --recover --max-lock 2m --conflict-resolve newer
--resync-mode CHOICE {#resync-mode}
In the event that a file differs on both sides during a --resync,
--resync-mode controls which version will overwrite the other. The supported
options are similar to --conflict-resolve. For all of
the following options, the version that is kept is referred to as the "winner",
and the version that is overwritten (deleted) is referred to as the "loser".
The options are named after the "winner":
path1- (the default) - the version from Path1 is unconditionally considered the winner (regardless ofmodtimeandsize, if any). This can be useful if one side is more trusted or up-to-date than the other, at the time of the--resync.path2- same aspath1, except the path2 version is considered the winner.newer- the newer file (bymodtime) is considered the winner, regardless of which side it came from. This may result in having a mix of some winners from Path1, and some winners from Path2. (The implementation is analogous to runningrclone copy --updatein both directions.)older- same asnewer, except the older file is considered the winner, and the newer file is considered the loser.larger- the larger file (bysize) is considered the winner (regardless ofmodtime, if any). This can be a useful option for remotes withoutmodtimesupport, or with the kinds of files (such as logs) that tend to grow but not shrink, over time.smaller- the smaller file (bysize) is considered the winner (regardless ofmodtime, if any).
For all of the above options, note the following:
- If either of the underlying remotes lacks support for the chosen method, it
will be ignored and will fall back to the default of
path1. (For example, if--resync-mode neweris set, but one of the paths uses a remote that doesn't supportmodtime.) - If a winner can't be determined because the chosen method's attribute is
missing or equal, it will be ignored, and bisync will instead try to determine
whether the files differ by looking at the other
--comparemethods in effect. (For example, if--resync-mode neweris set, but the Path1 and Path2 modtimes are identical, bisync will compare the sizes.) If bisync concludes that they differ, preference is given to whichever is the "source" at that moment. (In practice, this gives a slight advantage to Path2, as the 2to1 copy comes before the 1to2 copy.) If the files do not differ, nothing is copied (as both sides are already correct). - These options apply only to files that exist on both sides (with the same
name and relative path). Files that exist only on one side and not the other
are always copied to the other, during
--resync(this is one of the main differences between resync and non-resync runs.). --conflict-resolve,--conflict-loser, and--conflict-suffixdo not apply during--resync, and unlike these flags, nothing is renamed during--resync. When a file differs on both sides during--resync, one version always overwrites the other (much like inrclone copy.) (Consider using--backup-dirto retain a backup of the losing version.)- Unlike for
--conflict-resolve,--resync-mode noneis not a valid option (or rather, it will be interpreted as "no resync", unless--resynchas also been specified, in which case it will be ignored.) - Winners and losers are decided at the individual file-level only (there is
not currently an option to pick an entire winning directory atomically,
although the
path1andpath2options typically produce a similar result.) - To maintain backward-compatibility, the
--resyncflag implies--resync-mode path1unless a different--resync-modeis explicitly specified. Similarly, all--resync-modeoptions (exceptnone) imply--resync, so it is not necessary to use both the--resyncand--resync-modeflags simultaneously -- either one is sufficient without the other.
--check-access
Access check files are an additional safety measure against data loss.
bisync will ensure it can find matching RCLONE_TEST files in the same places
in the Path1 and Path2 filesystems.
RCLONE_TEST files are not generated automatically.
For --check-access to succeed, you must first either:
A) Place one or more RCLONE_TEST files in both systems, or
B) Set --check-filename to a filename already in use in various locations
throughout your sync'd fileset. Recommended methods for A) include:
rclone touch Path1/RCLONE_TEST(create a new file)rclone copyto Path1/RCLONE_TEST Path2/RCLONE_TEST(copy an existing file)rclone copy Path1/RCLONE_TEST Path2/RCLONE_TEST --include "RCLONE_TEST"(copy multiple files at once, recursively)- create the files manually (outside of rclone)
- run
bisynconce without--check-accessto set matching files on both filesystems will also work, but is not preferred, due to potential for user error (you are temporarily disabling the safety feature).
Note that --check-access is still enforced on --resync, so bisync --resync --check-access
will not work as a method of initially setting the files
(this is to ensure that bisync can't
inadvertently circumvent its own safety switch.)
Time stamps and file contents for RCLONE_TEST files are not important, just
the names and locations. If you have symbolic links in your sync tree it is
recommended to place RCLONE_TEST files in the linked-to directory tree to
protect against bisync assuming a bunch of deleted files if the linked-to tree
should not be accessible. See also the --check-filename flag.
--check-filename
Name of the file(s) used in access health validation.
The default --check-filename is RCLONE_TEST.
One or more files having this filename must exist, synchronized between your
source and destination filesets, in order for --check-access to succeed.
See --check-access for additional details.
--compare
As of v1.66, bisync fully supports comparing based on any combination of
size, modtime, and checksum (lifting the prior restriction on backends without
modtime support.)
By default (without the --compare flag), bisync inherits the same comparison
options as sync
(that is: size and modtime by default, unless modified with flags such as
--checksum or --size-only.)
If the --compare flag is set, it will override these defaults. This can be
useful if you wish to compare based on combinations not currently supported in
sync, such as comparing all three of size AND modtime AND checksum
simultaneously (or just modtime AND checksum).
--compare takes a comma-separated list, with the currently supported values
being size, modtime, and checksum. For example, if you want to compare
size and checksum, but not modtime, you would do:
--compare size,checksum
Or if you want to compare all three:
--compare size,modtime,checksum
--compare overrides any conflicting flags. For example, if you set the
conflicting flags --compare checksum --size-only, --size-only will be
ignored, and bisync will compare checksum and not size. To avoid confusion, it
is recommended to use either --compare or the normal sync flags, but not
both.
If --compare includes checksum and both remotes support checksums but have
no hash types in common with each other, checksums will be considered only
for comparisons within the same side (to determine what has changed since the
prior sync), but not for comparisons against the opposite side. If one side
supports checksums and the other does not, checksums will only be considered on
the side that supports them.
When comparing with checksum and/or size without modtime, bisync cannot
determine whether a file is newer or older -- only whether it is changed
or unchanged. (If it is changed on both sides, bisync still does the
standard equality-check to avoid declaring a sync conflict unless it absolutely
has to.)
It is recommended to do a --resync when changing --compare settings, as
otherwise your prior listing files may not contain the attributes you wish to
compare (for example, they will not have stored checksums if you were not
previously comparing checksums.)
--ignore-listing-checksum
When --checksum or --compare checksum is set, bisync will retrieve (or
generate) checksums (for backends that support them) when creating the listings
for both paths, and store the checksums in the listing files.
--ignore-listing-checksum will disable this behavior, which may speed things
up considerably, especially on backends (such as local) where hashes
must be computed on the fly instead of retrieved. Please note the following:
- As of
v1.66,--ignore-listing-checksumis now automatically set when neither--checksumnor--compare checksumare in use (as the checksums would not be used for anything.) --ignore-listing-checksumis NOT the same as--ignore-checksum, and you may wish to use one or the other, or both. In a nutshell:--ignore-listing-checksumcontrols whether checksums are considered when scanning for diffs, while--ignore-checksumcontrols whether checksums are considered during the copy/sync operations that follow, if there ARE diffs.- Unless
--ignore-listing-checksumis passed, bisync currently computes hashes for one path even when there's no common hash with the other path (for example, a crypt remote.) This can still be beneficial, as the hashes will still be used to detect changes within the same side (if--checksumor--compare checksumis set), even if they can't be used to compare against the opposite side. - If you wish to ignore listing checksums only on remotes where they are slow
to compute, consider using
--no-slow-hash(or--slow-hash-sync-only) instead of--ignore-listing-checksum. - If
--ignore-listing-checksumis used simultaneously with--compare checksum(or--checksum), checksums will be ignored for bisync deltas, but still considered during the sync operations that follow (if deltas are detected based on modtime and/or size.)
--no-slow-hash
On some remotes (notably local), checksums can dramatically slow down a bisync
run, because hashes cannot be stored and need to be computed in real-time when
they are requested. On other remotes (such as drive), they add practically no
time at all. The --no-slow-hash flag will automatically skip checksums on remotes
where they are slow, while still comparing them on others (assuming
--compare includes checksum.) This can be useful when one of your
bisync paths is slow but you still want to check checksums on the other, for a
more robust sync.
--slow-hash-sync-only
Same as --no-slow-hash, except slow hashes are still
considered during sync calls. They are still NOT considered for determining
deltas, nor or they included in listings. They are also skipped during
--resync. The main use case for this flag is when you have a large number of
files, but relatively few of them change from run to run -- so you don't want
to check your entire tree every time (it would take too long), but you still
want to consider checksums for the smaller group of files for which a modtime
or size change was detected. Keep in mind that this speed savings comes with
a safety trade-off: if a file's content were to change without a change to its
modtime or size, bisync would not detect it, and it would not be synced.
--slow-hash-sync-only is only useful if both remotes share a common hash
type (if they don't, bisync will automatically fall back to --no-slow-hash.)
Both --no-slow-hash and --slow-hash-sync-only have no effect without
--compare checksum (or --checksum).
--download-hash
If --download-hash is set, bisync will use best efforts to obtain an MD5
checksum by downloading and computing on-the-fly, when checksums are not
otherwise available (for example, a remote that doesn't support them.) Note
that since rclone has to download the entire file, this may dramatically slow
down your bisync runs, and is also likely to use a lot of data, so it is
probably not practical for bisync paths with a large total file size. However,
it can be a good option for syncing small-but-important files with maximum
accuracy (for example, a source code repo on a crypt remote.) An additional
advantage over methods like cryptcheck is
that the original file is not required for comparison (for example,
--download-hash can be used to bisync two different crypt remotes with
different passwords.)
When --download-hash is set, bisync still looks for more efficient checksums
first, and falls back to downloading only when none are found. It takes
priority over conflicting flags such as --no-slow-hash. --download-hash is
not suitable for Google Docs and other files of unknown size, as
their checksums would change from run to run (due to small variances in the
internals of the generated export file.) Therefore, bisync automatically skips
--download-hash for files with a size less than 0.
See also: Hasher backend,
cryptcheck command,
rclone check --download option,
md5sum command
--max-delete
As a safety check, if greater than the --max-delete percent of files were
deleted on either the Path1 or Path2 filesystem, then bisync will abort with
a warning message, without making any changes.
The default --max-delete is 50%.
One way to trigger this limit is to rename a directory that contains more
than half of your files. This will appear to bisync as a bunch of deleted
files and a bunch of new files.
This safety check is intended to block bisync from deleting all of the
files on both filesystems due to a temporary network access issue, or if
the user had inadvertently deleted the files on one side or the other.
To force the sync, either set a different delete percentage limit,
e.g. --max-delete 75 (allows up to 75% deletion), or use --force
to bypass the check.
Lines 1–500 of 2019. Load more
--- title: "Bisync" description: "Bidirectional cloud sync solution in rclone" versionIntroduced: "v1.58" --- ## Bisync `bisync` is considered an **advanced command**, so use with care. Make sure you have read and understood the entire [manual](https://rclone.org/bisync) (especially the [Limitations](#limitations) section) before using, or data loss can result. Questions can be asked in the [Rclone Forum](https://forum.rclone.org/). ## Getting started {#getting-started} - [Install rclone](/install/) and setup your remotes. - Bisync will create its working directory at `~/.cache/rclone/bisync` on Linux, `/Users/yourusername/Library/Caches/rclone/bisync` on Mac, or `C:\Users\MyLogin\AppData\Local\rclone\bisync` on Windows. Make sure that this location is writable. - Run bisync with the `--resync` flag, specifying the paths to the local and remote sync directory roots. - For successive sync runs, leave off the `--resync` flag. (**Important!**) - Consider using a [filters file](#filtering) for excluding unnecessary files and directories from the sync. - Consider setting up the [--check-access](#check-access) feature for safety. - On Linux or Mac, consider setting up a [crontab entry](#cron). bisync can safely run in concurrent cron jobs thanks to lock files it maintains. For example, your first command might look like this: ```console rclone bisync remote1:path1 remote2:path2 --create-empty-src-dirs --compare size,modtime,checksum --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync --dry-run ``` If all looks good, run it again without `--dry-run`. After that, remove `--resync` as well. Here is a typical run log (with timestamps removed for clarity): ```console rclone bisync /testdir/path1/ /testdir/path2/ --verbose INFO : Synching Path1 "/testdir/path1/" with Path2 "/testdir/path2/" INFO : Path1 checking for diffs INFO : - Path1 File is new - file11.txt INFO : - Path1 File is newer - file2.txt INFO : - Path1 File is newer - file5.txt INFO : - Path1 File is newer - file7.txt INFO : - Path1 File was deleted - file4.txt INFO : - Path1 File was deleted - file6.txt INFO : - Path1 File was deleted - file8.txt INFO : Path1: 7 changes: 1 new, 3 newer, 0 older, 3 deleted INFO : Path2 checking for diffs INFO : - Path2 File is new - file10.txt INFO : - Path2 File is newer - file1.txt INFO : - Path2 File is newer - file5.txt INFO : - Path2 File is newer - file6.txt INFO : - Path2 File was deleted - file3.txt INFO : - Path2 File was deleted - file7.txt INFO : - Path2 File was deleted - file8.txt INFO : Path2: 7 changes: 1 new, 3 newer, 0 older, 3 deleted INFO : Applying changes INFO : - Path1 Queue copy to Path2 - /testdir/path2/file11.txt INFO : - Path1 Queue copy to Path2 - /testdir/path2/file2.txt INFO : - Path2 Queue delete - /testdir/path2/file4.txt NOTICE: - WARNING New or changed in both paths - file5.txt NOTICE: - Path1 Renaming Path1 copy - /testdir/path1/file5.txt..path1 NOTICE: - Path1 Queue copy to Path2 - /testdir/path2/file5.txt..path1 NOTICE: - Path2 Renaming Path2 copy - /testdir/path2/file5.txt..path2 NOTICE: - Path2 Queue copy to Path1 - /testdir/path1/file5.txt..path2 INFO : - Path2 Queue copy to Path1 - /testdir/path1/file6.txt INFO : - Path1 Queue copy to Path2 - /testdir/path2/file7.txt INFO : - Path2 Queue copy to Path1 - /testdir/path1/file1.txt INFO : - Path2 Queue copy to Path1 - /testdir/path1/file10.txt INFO : - Path1 Queue delete - /testdir/path1/file3.txt INFO : - Path2 Do queued copies to - Path1 INFO : - Path1 Do queued copies to - Path2 INFO : - Do queued deletes on - Path1 INFO : - Do queued deletes on - Path2 INFO : Updating listings INFO : Validating listings for Path1 "/testdir/path1/" vs Path2 "/testdir/path2/" INFO : Bisync successful ``` ## Command line syntax ```console $ rclone bisync --help Usage: rclone bisync remote1:path1 remote2:path2 [flags] Positional arguments: Path1, Path2 Local path, or remote storage with ':' plus optional path. Type 'rclone listremotes' for list of configured remotes. Optional Flags: --backup-dir1 string --backup-dir for Path1. Must be a non-overlapping path on the same remote. --backup-dir2 string --backup-dir for Path2. Must be a non-overlapping path on the same remote. --check-access Ensure expected RCLONE_TEST files are found on both Path1 and Path2 filesystems, else abort. --check-filename string Filename for --check-access (default: RCLONE_TEST) --check-sync string Controls comparison of final listings: true|false|only (default: true) (default "true") --compare string Comma-separated list of bisync-specific compare options ex. 'size,modtime,checksum' (default: 'size,modtime') --conflict-loser ConflictLoserAction Action to take on the loser of a sync conflict (when there is a winner) or on both files (when there is no winner): , num, pathname, delete (default: num) --conflict-resolve string Automatically resolve conflicts by preferring the version that is: none, path1, path2, newer, older, larger, smaller (default: none) (default "none") --conflict-suffix string Suffix to use when renaming a --conflict-loser. Can be either one string or two comma-separated strings to assign different suffixes to Path1/Path2. (default: 'conflict') --create-empty-src-dirs Sync creation and deletion of empty directories. (Not compatible with --remove-empty-dirs) --download-hash Compute hash by downloading when otherwise unavailable. (warning: may be slow and use lots of data!) --filters-file string Read filtering patterns from a file --force Bypass --max-delete safety check and run the sync. Consider using with --verbose -h, --help help for bisync --ignore-listing-checksum Do not use checksums for listings (add --ignore-checksum to additionally skip post-copy checksum checks) --max-lock Duration Consider lock files older than this to be expired (default: 0 (never expire)) (minimum: 2m) (default 0s) --no-cleanup Retain working files (useful for troubleshooting and testing). --no-slow-hash Ignore listing checksums only on backends where they are slow --recover Automatically recover from interruptions without requiring --resync. --remove-empty-dirs Remove ALL empty directories at the final cleanup step. --resilient Allow future runs to retry after certain less-serious errors, instead of requiring --resync. -1, --resync Performs the resync run. Equivalent to --resync-mode path1. Consider using --verbose or --dry-run first. --resync-mode string During resync, prefer the version that is: path1, path2, newer, older, larger, smaller (default: path1 if --resync, otherwise none for no resync.) (default "none") --retries int Retry operations this many times if they fail (requires --resilient). (default 3) --retries-sleep Duration Interval between retrying operations if they fail, e.g. 500ms, 60s, 5m (0 to disable) (default 0s) --slow-hash-sync-only Ignore slow checksums for listings and deltas, but still consider them during sync calls. --workdir string Use custom working dir - useful for testing. (default: {WORKDIR}) --max-delete PERCENT Safety check on maximum percentage of deleted files allowed. If exceeded, the bisync run will abort. (default: 50%) -n, --dry-run Go through the motions - No files are copied/deleted. -v, --verbose Increases logging verbosity. May be specified more than once for more details. ``` Arbitrary rclone flags may be specified on the [bisync command line](/commands/rclone_bisync/), for example `rclone bisync ./testdir/path1/ gdrive:testdir/path2/ --drive-skip-gdocs -v -v --timeout 10s` Note that interactions of various rclone flags with bisync process flow has not been fully tested yet. ### Paths Path1 and Path2 arguments may be references to any mix of local directory paths (absolute or relative), UNC paths (`//server/share/path`), Windows drive paths (with a drive letter and `:`) or configured [remotes](/docs/#syntax-of-remote-paths) with optional subdirectory paths. Cloud references are distinguished by having a `:` in the argument (see [Windows support](#windows) below). Path1 and Path2 are treated equally, in that neither has priority for file changes (except during [`--resync`](#resync)), and access efficiency does not change whether a remote is on Path1 or Path2. The listings in bisync working directory (default: `~/.cache/rclone/bisync`) are named based on the Path1 and Path2 arguments so that separate syncs to individual directories within the tree may be set up, e.g.: `path_to_local_tree..dropbox_subdir.lst`. Any empty directories after the sync on both the Path1 and Path2 filesystems are not deleted by default, unless `--create-empty-src-dirs` is specified. If the `--remove-empty-dirs` flag is specified, then both paths will have ALL empty directories purged as the last step in the process. ## Command-line flags ### --resync This will effectively make both Path1 and Path2 filesystems contain a matching superset of all files. By default, Path2 files that do not exist in Path1 will be copied to Path1, and the process will then copy the Path1 tree to Path2. The `--resync` sequence is roughly equivalent to the following (but see [`--resync-mode`](#resync-mode) for other options): ```console rclone copy Path2 Path1 --ignore-existing [--create-empty-src-dirs] rclone copy Path1 Path2 [--create-empty-src-dirs] ``` The base directories on both Path1 and Path2 filesystems must exist or bisync will fail. This is required for safety - that bisync can verify that both paths are valid. When using `--resync`, a newer version of a file on the Path2 filesystem will (by default) be overwritten by the Path1 filesystem version. (Note that this is [NOT entirely symmetrical](https://github.com/rclone/rclone/issues/5681#issuecomment-938761815), and more symmetrical options can be specified with the [`--resync-mode`](#resync-mode) flag.) Carefully evaluate deltas using [--dry-run](/flags/#non-backend-flags). For a resync run, one of the paths may be empty (no files in the path tree). The resync run should result in files on both paths, else a normal non-resync run will fail. For a non-resync run, either path being empty (no files in the tree) fails with `Empty current PathN listing. Cannot sync to an empty directory: X.pathN.lst` This is a safety check that an unexpected empty path does not result in deleting **everything** in the other path. Note that `--resync` implies `--resync-mode path1` unless a different [`--resync-mode`](#resync-mode) is explicitly specified. It is not necessary to use both the `--resync` and `--resync-mode` flags -- either one is sufficient without the other. **Note:** `--resync` (including `--resync-mode`) should only be used under three specific (rare) circumstances: 1. It is your *first* bisync run (between these two paths) 2. You've just made changes to your bisync settings (such as editing the contents of your `--filters-file`) 3. There was an error on the prior run, and as a result, bisync now requires `--resync` to recover The rest of the time, you should *omit* `--resync`. The reason is because `--resync` will only *copy* (not *sync*) each side to the other. Therefore, if you included `--resync` for every bisync run, it would never be possible to delete a file -- the deleted file would always keep reappearing at the end of every run (because it's being copied from the other side where it still exists). Similarly, renaming a file would always result in a duplicate copy (both old and new name) on both sides. If you find that frequent interruptions from #3 are an issue, rather than automatically running `--resync`, the recommended alternative is to use the [`--resilient`](#resilient), [`--recover`](#recover), and [`--conflict-resolve`](#conflict-resolve) flags, (along with [Graceful Shutdown](#graceful-shutdown) mode, when needed) for a very robust "set-it-and-forget-it" bisync setup that can automatically bounce back from almost any interruption it might encounter. Consider adding something like the following: ```text --resilient --recover --max-lock 2m --conflict-resolve newer ``` ### --resync-mode CHOICE {#resync-mode} In the event that a file differs on both sides during a `--resync`, `--resync-mode` controls which version will overwrite the other. The supported options are similar to [`--conflict-resolve`](#conflict-resolve). For all of the following options, the version that is kept is referred to as the "winner", and the version that is overwritten (deleted) is referred to as the "loser". The options are named after the "winner": - `path1` - (the default) - the version from Path1 is unconditionally considered the winner (regardless of `modtime` and `size`, if any). This can be useful if one side is more trusted or up-to-date than the other, at the time of the `--resync`. - `path2` - same as `path1`, except the path2 version is considered the winner. - `newer` - the newer file (by `modtime`) is considered the winner, regardless of which side it came from. This may result in having a mix of some winners from Path1, and some winners from Path2. (The implementation is analogous to running `rclone copy --update` in both directions.) - `older` - same as `newer`, except the older file is considered the winner, and the newer file is considered the loser. - `larger` - the larger file (by `size`) is considered the winner (regardless of `modtime`, if any). This can be a useful option for remotes without `modtime` support, or with the kinds of files (such as logs) that tend to grow but not shrink, over time. - `smaller` - the smaller file (by `size`) is considered the winner (regardless of `modtime`, if any). For all of the above options, note the following: - If either of the underlying remotes lacks support for the chosen method, it will be ignored and will fall back to the default of `path1`. (For example, if `--resync-mode newer` is set, but one of the paths uses a remote that doesn't support `modtime`.) - If a winner can't be determined because the chosen method's attribute is missing or equal, it will be ignored, and bisync will instead try to determine whether the files differ by looking at the other `--compare` methods in effect. (For example, if `--resync-mode newer` is set, but the Path1 and Path2 modtimes are identical, bisync will compare the sizes.) If bisync concludes that they differ, preference is given to whichever is the "source" at that moment. (In practice, this gives a slight advantage to Path2, as the 2to1 copy comes before the 1to2 copy.) If the files *do not* differ, nothing is copied (as both sides are already correct). - These options apply only to files that exist on both sides (with the same name and relative path). Files that exist *only* on one side and not the other are *always* copied to the other, during `--resync` (this is one of the main differences between resync and non-resync runs.). - `--conflict-resolve`, `--conflict-loser`, and `--conflict-suffix` do not apply during `--resync`, and unlike these flags, nothing is renamed during `--resync`. When a file differs on both sides during `--resync`, one version always overwrites the other (much like in `rclone copy`.) (Consider using [`--backup-dir`](#backup-dir1-and-backup-dir2) to retain a backup of the losing version.) - Unlike for `--conflict-resolve`, `--resync-mode none` is not a valid option (or rather, it will be interpreted as "no resync", unless `--resync` has also been specified, in which case it will be ignored.) - Winners and losers are decided at the individual file-level only (there is not currently an option to pick an entire winning directory atomically, although the `path1` and `path2` options typically produce a similar result.) - To maintain backward-compatibility, the `--resync` flag implies `--resync-mode path1` unless a different `--resync-mode` is explicitly specified. Similarly, all `--resync-mode` options (except `none`) imply `--resync`, so it is not necessary to use both the `--resync` and `--resync-mode` flags simultaneously -- either one is sufficient without the other. ### --check-access Access check files are an additional safety measure against data loss. bisync will ensure it can find matching `RCLONE_TEST` files in the same places in the Path1 and Path2 filesystems. `RCLONE_TEST` files are not generated automatically. For `--check-access` to succeed, you must first either: **A)** Place one or more `RCLONE_TEST` files in both systems, or **B)** Set `--check-filename` to a filename already in use in various locations throughout your sync'd fileset. Recommended methods for **A)** include: - `rclone touch Path1/RCLONE_TEST` (create a new file) - `rclone copyto Path1/RCLONE_TEST Path2/RCLONE_TEST` (copy an existing file) - `rclone copy Path1/RCLONE_TEST Path2/RCLONE_TEST --include "RCLONE_TEST"` (copy multiple files at once, recursively) - create the files manually (outside of rclone) - run `bisync` once *without* `--check-access` to set matching files on both filesystems will also work, but is not preferred, due to potential for user error (you are temporarily disabling the safety feature). Note that `--check-access` is still enforced on `--resync`, so `bisync --resync --check-access` will not work as a method of initially setting the files (this is to ensure that bisync can't [inadvertently circumvent its own safety switch](https://forum.rclone.org/t/bisync-bugs-and-feature-requests/37636#:~:text=3.%20%2D%2Dcheck%2Daccess%20doesn%27t%20always%20fail%20when%20it%20should).) Time stamps and file contents for `RCLONE_TEST` files are not important, just the names and locations. If you have symbolic links in your sync tree it is recommended to place `RCLONE_TEST` files in the linked-to directory tree to protect against bisync assuming a bunch of deleted files if the linked-to tree should not be accessible. See also the [--check-filename](#check-filename) flag. ### --check-filename Name of the file(s) used in access health validation. The default `--check-filename` is `RCLONE_TEST`. One or more files having this filename must exist, synchronized between your source and destination filesets, in order for `--check-access` to succeed. See [--check-access](#check-access) for additional details. ### --compare As of `v1.66`, bisync fully supports comparing based on any combination of size, modtime, and checksum (lifting the prior restriction on backends without modtime support.) By default (without the `--compare` flag), bisync inherits the same comparison options as `sync` (that is: `size` and `modtime` by default, unless modified with flags such as [`--checksum`](/docs/#c-checksum) or [`--size-only`](/docs/#size-only).) If the `--compare` flag is set, it will override these defaults. This can be useful if you wish to compare based on combinations not currently supported in `sync`, such as comparing all three of `size` AND `modtime` AND `checksum` simultaneously (or just `modtime` AND `checksum`). `--compare` takes a comma-separated list, with the currently supported values being `size`, `modtime`, and `checksum`. For example, if you want to compare size and checksum, but not modtime, you would do: ```text --compare size,checksum ``` Or if you want to compare all three: ```text --compare size,modtime,checksum ``` `--compare` overrides any conflicting flags. For example, if you set the conflicting flags `--compare checksum --size-only`, `--size-only` will be ignored, and bisync will compare checksum and not size. To avoid confusion, it is recommended to use *either* `--compare` or the normal `sync` flags, but not both. If `--compare` includes `checksum` and both remotes support checksums but have no hash types in common with each other, checksums will be considered *only* for comparisons within the same side (to determine what has changed since the prior sync), but not for comparisons against the opposite side. If one side supports checksums and the other does not, checksums will only be considered on the side that supports them. When comparing with `checksum` and/or `size` without `modtime`, bisync cannot determine whether a file is `newer` or `older` -- only whether it is `changed` or `unchanged`. (If it is `changed` on both sides, bisync still does the standard equality-check to avoid declaring a sync conflict unless it absolutely has to.) It is recommended to do a `--resync` when changing `--compare` settings, as otherwise your prior listing files may not contain the attributes you wish to compare (for example, they will not have stored checksums if you were not previously comparing checksums.) ### --ignore-listing-checksum When `--checksum` or `--compare checksum` is set, bisync will retrieve (or generate) checksums (for backends that support them) when creating the listings for both paths, and store the checksums in the listing files. `--ignore-listing-checksum` will disable this behavior, which may speed things up considerably, especially on backends (such as [local](/local/)) where hashes must be computed on the fly instead of retrieved. Please note the following: - As of `v1.66`, `--ignore-listing-checksum` is now automatically set when neither `--checksum` nor `--compare checksum` are in use (as the checksums would not be used for anything.) - `--ignore-listing-checksum` is NOT the same as [`--ignore-checksum`](/docs/#ignore-checksum), and you may wish to use one or the other, or both. In a nutshell: `--ignore-listing-checksum` controls whether checksums are considered when scanning for diffs, while `--ignore-checksum` controls whether checksums are considered during the copy/sync operations that follow, if there ARE diffs. - Unless `--ignore-listing-checksum` is passed, bisync currently computes hashes for one path *even when there's no common hash with the other path* (for example, a [crypt](/crypt/#modification-times-and-hashes) remote.) This can still be beneficial, as the hashes will still be used to detect changes within the same side (if `--checksum` or `--compare checksum` is set), even if they can't be used to compare against the opposite side. - If you wish to ignore listing checksums *only* on remotes where they are slow to compute, consider using [`--no-slow-hash`](#no-slow-hash) (or [`--slow-hash-sync-only`](#slow-hash-sync-only)) instead of `--ignore-listing-checksum`. - If `--ignore-listing-checksum` is used simultaneously with `--compare checksum` (or `--checksum`), checksums will be ignored for bisync deltas, but still considered during the sync operations that follow (if deltas are detected based on modtime and/or size.) ### --no-slow-hash On some remotes (notably `local`), checksums can dramatically slow down a bisync run, because hashes cannot be stored and need to be computed in real-time when they are requested. On other remotes (such as `drive`), they add practically no time at all. The `--no-slow-hash` flag will automatically skip checksums on remotes where they are slow, while still comparing them on others (assuming [`--compare`](#compare) includes `checksum`.) This can be useful when one of your bisync paths is slow but you still want to check checksums on the other, for a more robust sync. ### --slow-hash-sync-only Same as [`--no-slow-hash`](#no-slow-hash), except slow hashes are still considered during sync calls. They are still NOT considered for determining deltas, nor or they included in listings. They are also skipped during `--resync`. The main use case for this flag is when you have a large number of files, but relatively few of them change from run to run -- so you don't want to check your entire tree every time (it would take too long), but you still want to consider checksums for the smaller group of files for which a `modtime` or `size` change was detected. Keep in mind that this speed savings comes with a safety trade-off: if a file's content were to change without a change to its `modtime` or `size`, bisync would not detect it, and it would not be synced. `--slow-hash-sync-only` is only useful if both remotes share a common hash type (if they don't, bisync will automatically fall back to `--no-slow-hash`.) Both `--no-slow-hash` and `--slow-hash-sync-only` have no effect without `--compare checksum` (or `--checksum`). ### --download-hash If `--download-hash` is set, bisync will use best efforts to obtain an MD5 checksum by downloading and computing on-the-fly, when checksums are not otherwise available (for example, a remote that doesn't support them.) Note that since rclone has to download the entire file, this may dramatically slow down your bisync runs, and is also likely to use a lot of data, so it is probably not practical for bisync paths with a large total file size. However, it can be a good option for syncing small-but-important files with maximum accuracy (for example, a source code repo on a `crypt` remote.) An additional advantage over methods like [`cryptcheck`](/commands/rclone_cryptcheck/) is that the original file is not required for comparison (for example, `--download-hash` can be used to bisync two different crypt remotes with different passwords.) When `--download-hash` is set, bisync still looks for more efficient checksums first, and falls back to downloading only when none are found. It takes priority over conflicting flags such as `--no-slow-hash`. `--download-hash` is not suitable for [Google Docs](#gdocs) and other files of unknown size, as their checksums would change from run to run (due to small variances in the internals of the generated export file.) Therefore, bisync automatically skips `--download-hash` for files with a size less than 0. See also: [`Hasher`](/hasher/) backend, [`cryptcheck`](/commands/rclone_cryptcheck/) command, [`rclone check --download`](/commands/rclone_check/) option, [`md5sum`](/commands/rclone_md5sum/) command ### --max-delete As a safety check, if greater than the `--max-delete` percent of files were deleted on either the Path1 or Path2 filesystem, then bisync will abort with a warning message, without making any changes. The default `--max-delete` is `50%`. One way to trigger this limit is to rename a directory that contains more than half of your files. This will appear to bisync as a bunch of deleted files and a bunch of new files. This safety check is intended to block bisync from deleting all of the files on both filesystems due to a temporary network access issue, or if the user had inadvertently deleted the files on one side or the other. To force the sync, either set a different delete percentage limit, e.g. `--max-delete 75` (allows up to 75% deletion), or use `--force` to bypass the check.