title: "Bisync" description: "Bidirectional cloud sync solution in rclone" versionIntroduced: "v1.58"
Getting started {#getting-started}
- Install rclone and setup your remotes.
- Bisync will create its working directory
at
~/.cache/rclone/bisyncon Linux 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. - 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, consider setting up a crontab entry. bisync can safely run in concurrent cron jobs thanks to lock files it maintains.
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:
--check-access Ensure expected `RCLONE_TEST` files are found on
both Path1 and Path2 filesystems, else abort.
--check-filename FILENAME Filename for `--check-access` (default: `RCLONE_TEST`)
--check-sync CHOICE Controls comparison of final listings:
`true | false | only` (default: true)
If set to `only`, bisync will only compare listings
from the last run but skip actual sync.
--filters-file PATH Read filtering patterns from a file
--max-delete PERCENT Safety check on maximum percentage of deleted files allowed.
If exceeded, the bisync run will abort. (default: 50%)
--force Bypass `--max-delete` safety check and run the sync.
Consider using with `--verbose`
--remove-empty-dirs Remove empty directories at the final cleanup step.
-1, --resync Performs the resync run.
Warning: Path1 files may overwrite Path2 versions.
Consider using `--verbose` or `--dry-run` first.
--localtime Use local time in listings (default: UTC)
--no-cleanup Retain working files (useful for troubleshooting and testing).
--workdir PATH Use custom working directory (useful for testing).
(default: `~/.cache/rclone/bisync`)
-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.
-h, --help help for bisync
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, 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. If the --remove-empty-dirs
flag is specified, then both paths will have any 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. Path2 files that do not exist in Path1 will be copied to Path1, and the process will then sync the Path1 tree to Path2.
The base directories on the 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 either on Path1 or Path2
filesystem, will overwrite the file on the other path (only the last version
will be kept). 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.
--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-accessto succeed, you must first either:
A) Place one or more RCLONE_TEST files in the Path1 or Path2 filesystem
and then do either a run without --check-access or a --resync to
set matching files on both filesystems, or
B) Set --check-filename to a filename already in use in various locations
throughout your sync'd fileset.
Time stamps and file contents 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.
--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.
Also see the all files changed check.
--filters-file {#filters-file}
By using rclone filter features you can exclude file types or directory sub-trees from the sync. See the bisync filters section and generic --filter-from documentation. An example filters file contains filters for non-allowed files for synching with Dropbox.
If you make changes to your filters file then bisync requires a run
with --resync. This is a safety feature, which avoids existing files
on the Path1 and/or Path2 side from seeming to disappear from view
(since they are excluded in the new listings), which would fool bisync
into seeing them as deleted (as compared to the prior run listings),
and then bisync would proceed to delete them for real.
To block this from happening bisync calculates an MD5 hash of the filters file
and stores the hash in a .md5 file in the same place as your filters file.
On the next runs with --filters-file set, bisync re-calculates the MD5 hash
of the current filters file and compares it to the hash stored in .md5 file.
If they don't match the run aborts with a critical error and thus forces you
to do a --resync, likely avoiding a disaster.
--check-sync
Enabled by default, the check-sync function checks that all of the same files exist in both the Path1 and Path2 history listings. This check-sync integrity check is performed at the end of the sync run by default. Any untrapped failing copy/deletes between the two paths might result in differences between the two listings and in the untracked file content differences between the two paths. A resync run would correct the error.
Note that the default-enabled integrity check locally executes a load of both
the final Path1 and Path2 listings, and thus adds to the run time of a sync.
Using --check-sync=false will disable it and may significantly reduce the
sync run times for very large numbers of files.
The check may be run manually with --check-sync=only. It runs only the
integrity check and terminates without actually synching.
Operation
Runtime flow details
bisync retains the listings of the Path1 and Path2 filesystems
from the prior run.
On each successive run it will:
- list files on
path1andpath2, and check for changes on each side. Changes includeNew,Newer,Older, andDeletedfiles. - Propagate changes on
path1topath2, and vice-versa.
Safety measures
- Lock file prevents multiple simultaneous runs when taking a while. This can be particularly useful if bisync is run by cron scheduler.
- Handle change conflicts non-destructively by creating
..path1and..path2file versions. - File system access health check using
RCLONE_TESTfiles (see the--check-accessflag). - Abort on excessive deletes - protects against a failed listing
being interpreted as all the files were deleted.
See the
--max-deleteand--forceflags. - If something evil happens, bisync goes into a safe state to block damage by later runs. (See Error Handling)
Normal sync checks
| Type | Description | Result | Implementation |
|---|---|---|---|
| Path2 new | File is new on Path2, does not exist on Path1 | Path2 version survives | rclone copy Path2 to Path1 |
| Path2 newer | File is newer on Path2, unchanged on Path1 | Path2 version survives | rclone copy Path2 to Path1 |
| Path2 deleted | File is deleted on Path2, unchanged on Path1 | File is deleted | rclone delete Path1 |
| Path1 new | File is new on Path1, does not exist on Path2 | Path1 version survives | rclone copy Path1 to Path2 |
| Path1 newer | File is newer on Path1, unchanged on Path2 | Path1 version survives | rclone copy Path1 to Path2 |
| Path1 older | File is older on Path1, unchanged on Path2 | Path1 version survives | rclone copy Path1 to Path2 |
| Path2 older | File is older on Path2, unchanged on Path1 | Path2 version survives | rclone copy Path2 to Path1 |
| Path1 deleted | File no longer exists on Path1 | File is deleted | rclone delete Path2 |
Unusual sync checks
| Type | Description | Result | Implementation |
|---|---|---|---|
| Path1 new AND Path2 new | File is new on Path1 AND new on Path2 | Files renamed to _Path1 and _Path2 | rclone copy _Path2 file to Path1, rclone copy _Path1 file to Path2 |
| Path2 newer AND Path1 changed | File is newer on Path2 AND also changed (newer/older/size) on Path1 | Files renamed to _Path1 and _Path2 | rclone copy _Path2 file to Path1, rclone copy _Path1 file to Path2 |
| Path2 newer AND Path1 deleted | File is newer on Path2 AND also deleted on Path1 | Path2 version survives | rclone copy Path2 to Path1 |
| Path2 deleted AND Path1 changed | File is deleted on Path2 AND changed (newer/older/size) on Path1 | Path1 version survives | rclone copy Path1 to Path2 |
| Path1 deleted AND Path2 changed | File is deleted on Path1 AND changed (newer/older/size) on Path2 | Path2 version survives | rclone copy Path2 to Path1 |
All files changed check {#all-files-changed}
if all prior existing files on either of the filesystems have changed
(e.g. timestamps have changed due to changing the system's timezone)
then bisync will abort without making any changes.
Any new files are not considered for this check. You could use --force
to force the sync (whichever side has the changed timestamp files wins).
Alternately, a --resync may be used (Path1 versions will be pushed
to Path2). Consider the situation carefully and perhaps use --dry-run
before you commit to the changes.
Modification time
Bisync relies on file timestamps to identify changed files and will refuse to operate if backend lacks the modification time support.
If you or your application should change the content of a file without changing the modification time then bisync will not notice the change, and thus will not copy it to the other side.
Note that on some cloud storage systems it is not possible to have file timestamps that match precisely between the local and other filesystems.
Bisync's approach to this problem is by tracking the changes on each side separately over time with a local database of files in that side then applying the resulting changes on the other side.
Error handling {#error-handling}
Certain bisync critical errors, such as file copy/move failing, will result in
a bisync lockout of following runs. The lockout is asserted because the sync
status and history of the Path1 and Path2 filesystems cannot be trusted,
so it is safer to block any further changes until someone checks things out.
The recovery is to do a --resync again.
It is recommended to use --resync --dry-run --verbose initially and
carefully review what changes will be made before running the --resync
without --dry-run.
Most of these events come up due to a error status from an internal call.
On such a critical error the {...}.path1.lst and {...}.path2.lst
listing files are renamed to extension .lst-err, which blocks any future
bisync runs (since the normal .lst files are not found).
Bisync keeps them under bisync subdirectory of the rclone cache directory,
typically at ${HOME}/.cache/rclone/bisync/ on Linux.
Some errors are considered temporary and re-running the bisync is not blocked. The critical return blocks further bisync runs.
Lock file
When bisync is running, a lock file is created in the bisync working directory,
typically at ~/.cache/rclone/bisync/PATH1..PATH2.lck on Linux.
If bisync should crash or hang, the lock file will remain in place and block
any further runs of bisync for the same paths.
Delete the lock file as part of debugging the situation.
The lock file effectively blocks follow-on (e.g., scheduled by cron) runs
when the prior invocation is taking a long time.
The lock file contains PID of the blocking process, which may help in debug.
Note that while concurrent bisync runs are allowed, be very cautious that there is no overlap in the trees being synched between concurrent runs, lest there be replicated files, deleted files and general mayhem.
Return codes
rclone bisync returns the following codes to calling program:
0on a successful run,1for a non-critical failing run (a rerun may be successful),2for a critically aborted run (requires a--resyncto recover).
Limitations
Supported backends
Bisync is considered BETA and has been tested with the following backends:
- Local filesystem
- Google Drive
- Dropbox
- OneDrive
- S3
- SFTP
- Yandex Disk
It has not been fully tested with other services yet. If it works, or sorta works, please let us know and we'll update the list. Run the test suite to check for proper operation as described below.
First release of rclone bisync requires that underlying backend supported
the modification time feature and will refuse to run otherwise.
This limitation will be lifted in a future rclone bisync release.
Concurrent modifications
When using Local, FTP or SFTP remotes rclone does not create temporary files at the destination when copying, and thus if the connection is lost the created file may be corrupt, which will likely propagate back to the original path on the next sync, resulting in data loss. This will be solved in a future release, there is no workaround at the moment.
Files that change during a bisync run may result in data loss. This has been seen in a highly dynamic environment, where the filesystem is getting hammered by running processes during the sync. The solution is to sync at quiet times or filter out unnecessary directories and files.
Empty directories
New empty directories on one path are not propagated to the other side. This is because bisync (and rclone) natively works on files not directories. The following sequence is a workaround but will not propagate the delete of an empty directory to the other side:
rclone bisync PATH1 PATH2
rclone copy PATH1 PATH2 --filter "+ */" --filter "- **" --create-empty-src-dirs
rclone copy PATH2 PATH2 --filter "+ */" --filter "- **" --create-empty-src-dirs
Renamed directories
Renaming a folder on the Path1 side results is deleting all files on
the Path2 side and then copying all files again from Path1 to Path2.
Bisync sees this as all files in the old directory name as deleted and all
files in the new directory name as new. Similarly, renaming a directory on
both sides to the same name will result in creating ..path1 and ..path2
files on both sides.
Currently the most effective and efficient method of renaming a directory
is to rename it on both sides, then do a --resync.
Case sensitivity
Synching with case-insensitive filesystems, such as Windows or Box,
can result in file name conflicts. This will be fixed in a future release.
The near term workaround is to make sure that files on both sides
don't have spelling case differences (Smile.jpg vs. smile.jpg).
Windows support {#windows}
Bisync has been tested on Windows 8.1, Windows 10 Pro 64-bit and on Windows GitHub runners.
Drive letters are allowed, including drive letters mapped to network drives
(rclone bisync J:\localsync GDrive:).
If a drive letter is omitted, the shell current drive is the default.
Drive letters are a single character follows by :, so cloud names
must be more than one character long.
Absolute paths (with or without a drive letter), and relative paths (with or without a drive letter) are supported.
Working directory is created at C:\Users\MyLogin\AppData\Local\rclone\bisync.
Note that bisync output may show a mix of forward / and back \ slashes.
Be careful of case independent directory and file naming on Windows vs. case dependent Linux
Filtering {#filtering}
See filtering documentation for how filter rules are written and interpreted.
Bisync's --filters-file flag slightly extends the rclone's
--filter-from
filtering mechanism.
For a given bisync run you may provide only one --filters-file.
The --include*, --exclude*, and --filter flags are also supported.
How to filter directories
Filtering portions of the directory tree is a critical feature for synching.
Examples of directory trees (always beneath the Path1/Path2 root level) you may want to exclude from your sync:
- Directory trees containing only software build intermediate files.
- Directory trees containing application temporary files and data
such as the Windows
C:\Users\MyLogin\AppData\tree. - Directory trees containing files that are large, less important, or are getting thrashed continuously by ongoing processes.
On the other hand, there may be only select directories that you actually want to sync, and exclude all others. See the Example include-style filters for Windows user directories below.
Filters file writing guidelines
- Begin with excluding directory trees:
- e.g.
- /AppData/ **on the end is not necessary. Once a given directory level is excluded then everything beneath it won't be looked at by rclone.- Exclude such directories that are unneeded, are big, dynamically thrashed, or where there may be access permission issues.
- Excluding such dirs first will make rclone operations (much) faster.
- Specific files may also be excluded, as with the Dropbox exclusions example below.
- e.g.
- Decide if its easier (or cleaner) to:
- Include select directories and therefore exclude everything else -- or --
- Exclude select directories and therefore include everything else
- Include select directories:
- Add lines like:
+ /Documents/PersonalFiles/**to select which directories to include in the sync.
- Add lines like:
Lines 1–500 of 1104. Load more
--- title: "Bisync" description: "Bidirectional cloud sync solution in rclone" versionIntroduced: "v1.58" --- ## Getting started {#getting-started} - [Install rclone](/install/) and setup your remotes. - Bisync will create its working directory at `~/.cache/rclone/bisync` on Linux 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. - 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, consider setting up a [crontab entry](#cron). bisync can safely run in concurrent cron jobs thanks to lock files it maintains. 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: --check-access Ensure expected `RCLONE_TEST` files are found on both Path1 and Path2 filesystems, else abort. --check-filename FILENAME Filename for `--check-access` (default: `RCLONE_TEST`) --check-sync CHOICE Controls comparison of final listings: `true | false | only` (default: true) If set to `only`, bisync will only compare listings from the last run but skip actual sync. --filters-file PATH Read filtering patterns from a file --max-delete PERCENT Safety check on maximum percentage of deleted files allowed. If exceeded, the bisync run will abort. (default: 50%) --force Bypass `--max-delete` safety check and run the sync. Consider using with `--verbose` --remove-empty-dirs Remove empty directories at the final cleanup step. -1, --resync Performs the resync run. Warning: Path1 files may overwrite Path2 versions. Consider using `--verbose` or `--dry-run` first. --localtime Use local time in listings (default: UTC) --no-cleanup Retain working files (useful for troubleshooting and testing). --workdir PATH Use custom working directory (useful for testing). (default: `~/.cache/rclone/bisync`) -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. -h, --help help for bisync ``` 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, 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. If the `--remove-empty-dirs` flag is specified, then both paths will have any 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. Path2 files that do not exist in Path1 will be copied to Path1, and the process will then sync the Path1 tree to Path2. The base directories on the 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 either on Path1 or Path2 filesystem, will overwrite the file on the other path (only the last version will be kept). 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. #### --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 the Path1 or Path2 filesystem and then do either a run without `--check-access` or a [--resync](#resync) to set matching files on both filesystems, or **B)** Set `--check-filename` to a filename already in use in various locations throughout your sync'd fileset. Time stamps and file contents 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. #### --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. Also see the [all files changed](#all-files-changed) check. #### --filters-file {#filters-file} By using rclone filter features you can exclude file types or directory sub-trees from the sync. See the [bisync filters](#filtering) section and generic [--filter-from](/filtering/#filter-from-read-filtering-patterns-from-a-file) documentation. An [example filters file](#example-filters-file) contains filters for non-allowed files for synching with Dropbox. If you make changes to your filters file then bisync requires a run with `--resync`. This is a safety feature, which avoids existing files on the Path1 and/or Path2 side from seeming to disappear from view (since they are excluded in the new listings), which would fool bisync into seeing them as deleted (as compared to the prior run listings), and then bisync would proceed to delete them for real. To block this from happening bisync calculates an MD5 hash of the filters file and stores the hash in a `.md5` file in the same place as your filters file. On the next runs with `--filters-file` set, bisync re-calculates the MD5 hash of the current filters file and compares it to the hash stored in `.md5` file. If they don't match the run aborts with a critical error and thus forces you to do a `--resync`, likely avoiding a disaster. #### --check-sync Enabled by default, the check-sync function checks that all of the same files exist in both the Path1 and Path2 history listings. This _check-sync_ integrity check is performed at the end of the sync run by default. Any untrapped failing copy/deletes between the two paths might result in differences between the two listings and in the untracked file content differences between the two paths. A resync run would correct the error. Note that the default-enabled integrity check locally executes a load of both the final Path1 and Path2 listings, and thus adds to the run time of a sync. Using `--check-sync=false` will disable it and may significantly reduce the sync run times for very large numbers of files. The check may be run manually with `--check-sync=only`. It runs only the integrity check and terminates without actually synching. ## Operation ### Runtime flow details bisync retains the listings of the `Path1` and `Path2` filesystems from the prior run. On each successive run it will: - list files on `path1` and `path2`, and check for changes on each side. Changes include `New`, `Newer`, `Older`, and `Deleted` files. - Propagate changes on `path1` to `path2`, and vice-versa. ### Safety measures - Lock file prevents multiple simultaneous runs when taking a while. This can be particularly useful if bisync is run by cron scheduler. - Handle change conflicts non-destructively by creating `..path1` and `..path2` file versions. - File system access health check using `RCLONE_TEST` files (see the `--check-access` flag). - Abort on excessive deletes - protects against a failed listing being interpreted as all the files were deleted. See the `--max-delete` and `--force` flags. - If something evil happens, bisync goes into a safe state to block damage by later runs. (See [Error Handling](#error-handling)) ### Normal sync checks Type | Description | Result | Implementation --------------|-----------------------------------------------|--------------------------|----------------------------- Path2 new | File is new on Path2, does not exist on Path1 | Path2 version survives | `rclone copy` Path2 to Path1 Path2 newer | File is newer on Path2, unchanged on Path1 | Path2 version survives | `rclone copy` Path2 to Path1 Path2 deleted | File is deleted on Path2, unchanged on Path1 | File is deleted | `rclone delete` Path1 Path1 new | File is new on Path1, does not exist on Path2 | Path1 version survives | `rclone copy` Path1 to Path2 Path1 newer | File is newer on Path1, unchanged on Path2 | Path1 version survives | `rclone copy` Path1 to Path2 Path1 older | File is older on Path1, unchanged on Path2 | _Path1 version survives_ | `rclone copy` Path1 to Path2 Path2 older | File is older on Path2, unchanged on Path1 | _Path2 version survives_ | `rclone copy` Path2 to Path1 Path1 deleted | File no longer exists on Path1 | File is deleted | `rclone delete` Path2 ### Unusual sync checks Type | Description | Result | Implementation --------------------------------|---------------------------------------|------------------------------------|----------------------- Path1 new AND Path2 new | File is new on Path1 AND new on Path2 | Files renamed to _Path1 and _Path2 | `rclone copy` _Path2 file to Path1, `rclone copy` _Path1 file to Path2 Path2 newer AND Path1 changed | File is newer on Path2 AND also changed (newer/older/size) on Path1 | Files renamed to _Path1 and _Path2 | `rclone copy` _Path2 file to Path1, `rclone copy` _Path1 file to Path2 Path2 newer AND Path1 deleted | File is newer on Path2 AND also deleted on Path1 | Path2 version survives | `rclone copy` Path2 to Path1 Path2 deleted AND Path1 changed | File is deleted on Path2 AND changed (newer/older/size) on Path1 | Path1 version survives |`rclone copy` Path1 to Path2 Path1 deleted AND Path2 changed | File is deleted on Path1 AND changed (newer/older/size) on Path2 | Path2 version survives | `rclone copy` Path2 to Path1 ### All files changed check {#all-files-changed} if _all_ prior existing files on either of the filesystems have changed (e.g. timestamps have changed due to changing the system's timezone) then bisync will abort without making any changes. Any new files are not considered for this check. You could use `--force` to force the sync (whichever side has the changed timestamp files wins). Alternately, a `--resync` may be used (Path1 versions will be pushed to Path2). Consider the situation carefully and perhaps use `--dry-run` before you commit to the changes. ### Modification time Bisync relies on file timestamps to identify changed files and will _refuse_ to operate if backend lacks the modification time support. If you or your application should change the content of a file without changing the modification time then bisync will _not_ notice the change, and thus will not copy it to the other side. Note that on some cloud storage systems it is not possible to have file timestamps that match _precisely_ between the local and other filesystems. Bisync's approach to this problem is by tracking the changes on each side _separately_ over time with a local database of files in that side then applying the resulting changes on the other side. ### Error handling {#error-handling} Certain bisync critical errors, such as file copy/move failing, will result in a bisync lockout of following runs. The lockout is asserted because the sync status and history of the Path1 and Path2 filesystems cannot be trusted, so it is safer to block any further changes until someone checks things out. The recovery is to do a `--resync` again. It is recommended to use `--resync --dry-run --verbose` initially and _carefully_ review what changes will be made before running the `--resync` without `--dry-run`. Most of these events come up due to a error status from an internal call. On such a critical error the `{...}.path1.lst` and `{...}.path2.lst` listing files are renamed to extension `.lst-err`, which blocks any future bisync runs (since the normal `.lst` files are not found). Bisync keeps them under `bisync` subdirectory of the rclone cache directory, typically at `${HOME}/.cache/rclone/bisync/` on Linux. Some errors are considered temporary and re-running the bisync is not blocked. The _critical return_ blocks further bisync runs. ### Lock file When bisync is running, a lock file is created in the bisync working directory, typically at `~/.cache/rclone/bisync/PATH1..PATH2.lck` on Linux. If bisync should crash or hang, the lock file will remain in place and block any further runs of bisync _for the same paths_. Delete the lock file as part of debugging the situation. The lock file effectively blocks follow-on (e.g., scheduled by _cron_) runs when the prior invocation is taking a long time. The lock file contains _PID_ of the blocking process, which may help in debug. **Note** that while concurrent bisync runs are allowed, _be very cautious_ that there is no overlap in the trees being synched between concurrent runs, lest there be replicated files, deleted files and general mayhem. ### Return codes `rclone bisync` returns the following codes to calling program: - `0` on a successful run, - `1` for a non-critical failing run (a rerun may be successful), - `2` for a critically aborted run (requires a `--resync` to recover). ## Limitations ### Supported backends Bisync is considered _BETA_ and has been tested with the following backends: - Local filesystem - Google Drive - Dropbox - OneDrive - S3 - SFTP - Yandex Disk It has not been fully tested with other services yet. If it works, or sorta works, please let us know and we'll update the list. Run the test suite to check for proper operation as described below. First release of `rclone bisync` requires that underlying backend supported the modification time feature and will refuse to run otherwise. This limitation will be lifted in a future `rclone bisync` release. ### Concurrent modifications When using **Local, FTP or SFTP** remotes rclone does not create _temporary_ files at the destination when copying, and thus if the connection is lost the created file may be corrupt, which will likely propagate back to the original path on the next sync, resulting in data loss. This will be solved in a future release, there is no workaround at the moment. Files that **change during** a bisync run may result in data loss. This has been seen in a highly dynamic environment, where the filesystem is getting hammered by running processes during the sync. The solution is to sync at quiet times or [filter out](#filtering) unnecessary directories and files. ### Empty directories New empty directories on one path are _not_ propagated to the other side. This is because bisync (and rclone) natively works on files not directories. The following sequence is a workaround but will not propagate the delete of an empty directory to the other side: ``` rclone bisync PATH1 PATH2 rclone copy PATH1 PATH2 --filter "+ */" --filter "- **" --create-empty-src-dirs rclone copy PATH2 PATH2 --filter "+ */" --filter "- **" --create-empty-src-dirs ``` ### Renamed directories Renaming a folder on the Path1 side results is deleting all files on the Path2 side and then copying all files again from Path1 to Path2. Bisync sees this as all files in the old directory name as deleted and all files in the new directory name as new. Similarly, renaming a directory on both sides to the same name will result in creating `..path1` and `..path2` files on both sides. Currently the most effective and efficient method of renaming a directory is to rename it on both sides, then do a `--resync`. ### Case sensitivity Synching with **case-insensitive** filesystems, such as Windows or `Box`, can result in file name conflicts. This will be fixed in a future release. The near term workaround is to make sure that files on both sides don't have spelling case differences (`Smile.jpg` vs. `smile.jpg`). ## Windows support {#windows} Bisync has been tested on Windows 8.1, Windows 10 Pro 64-bit and on Windows GitHub runners. Drive letters are allowed, including drive letters mapped to network drives (`rclone bisync J:\localsync GDrive:`). If a drive letter is omitted, the shell current drive is the default. Drive letters are a single character follows by `:`, so cloud names must be more than one character long. Absolute paths (with or without a drive letter), and relative paths (with or without a drive letter) are supported. Working directory is created at `C:\Users\MyLogin\AppData\Local\rclone\bisync`. Note that bisync output may show a mix of forward `/` and back `\` slashes. Be careful of case independent directory and file naming on Windows vs. case dependent Linux ## Filtering {#filtering} See [filtering documentation](/filtering/) for how filter rules are written and interpreted. Bisync's [`--filters-file`](#filters-file) flag slightly extends the rclone's [--filter-from](/filtering/#filter-from-read-filtering-patterns-from-a-file) filtering mechanism. For a given bisync run you may provide _only one_ `--filters-file`. The `--include*`, `--exclude*`, and `--filter` flags are also supported. ### How to filter directories Filtering portions of the directory tree is a critical feature for synching. Examples of directory trees (always beneath the Path1/Path2 root level) you may want to exclude from your sync: - Directory trees containing only software build intermediate files. - Directory trees containing application temporary files and data such as the Windows `C:\Users\MyLogin\AppData\` tree. - Directory trees containing files that are large, less important, or are getting thrashed continuously by ongoing processes. On the other hand, there may be only select directories that you actually want to sync, and exclude all others. See the [Example include-style filters for Windows user directories](#include-filters) below. ### Filters file writing guidelines 1. Begin with excluding directory trees: - e.g. `- /AppData/` - `**` on the end is not necessary. Once a given directory level is excluded then everything beneath it won't be looked at by rclone. - Exclude such directories that are unneeded, are big, dynamically thrashed, or where there may be access permission issues. - Excluding such dirs first will make rclone operations (much) faster. - Specific files may also be excluded, as with the Dropbox exclusions example below. 2. Decide if its easier (or cleaner) to: - Include select directories and therefore _exclude everything else_ -- or -- - Exclude select directories and therefore _include everything else_ 3. Include select directories: - Add lines like: `+ /Documents/PersonalFiles/**` to select which directories to include in the sync.