Synchronization

How a sync finds what changed on each side, decides what each file needs, and runs only what you confirm.

The memory of the last sync

For every file it synchronizes, sync-servers records both sides as they were at that moment: the size and modification time of the local copy and of the server copy. These sync records are kept per site and server in the state folder of this computer.

On the next sync each side is compared with its own record, never with the other side's clock. A local file whose size or time moved is changed locally; a server file whose size or time moved is changed on the server. When both moved, the file changed on both sides, and it waits for your decision instead of being overwritten. A local file is held to its record exactly, since the disk reports the same time for a file nobody touched. On the server, times closer than the tolerance, 2 seconds by default, count as equal, because many servers round them in listings.

A file with no record yet, as on a first sync, is compared across the two sides: the newer copy wins, and copies of the same age that differ ask for a decision. In checksum mode (sync.compare set to checksum) SHA-256 hashes settle what times cannot.

sync-servers status shows what changed on each side without planning anything. mark-synced records files as in sync without moving them, and state reset forgets the records so the next sync starts from scratch.

From a change to an action

Each direction turns what changed into an action. A file whose row says "not listed" is counted as skipped and never moves.

The action each change gets, by direction
What happened since the last syncPut newer filesGet newer filesBoth
Changed herePutnot listedPut
Changed on the servernot listedGetGet
Changed on both sidesResolveResolveResolve
New herePutnot listedPut
New on the servernot listedGetGet
Deleted on the server, unchanged herePut againnot listedPut again
Deleted here, unchanged on the servernot listedGet againGet again
Changed here, deleted on the serverResolveResolveResolve
Deleted here, changed on the serverResolveResolveResolve
No record, newer herePutnot listedPut
No record, newer on the servernot listedGetGet
No record, differs, same ageResolveResolveResolve

A Resolve row is unchecked and cannot run until you choose Put, Get, Skip or Synchronized for it.

The delete option

With --delete, or the delete checkbox, a file missing on the other side is offered for deletion instead of being copied back. The checkbox is worded for the direction: Delete remote files not on local drive when putting, Delete local files not on remote server when getting.

What the delete option changes
What happenedPut newer filesGet newer filesBoth
Deleted here since the last syncDelete on the server, checkedGet againDelete on the server, checked
Deleted on the server since the last syncPut againDelete here, checkedPut again
On the server only, never synchronizedDelete on the server, uncheckedGetDelete on the server, unchecked
Here only, never synchronizedPutDelete here, uncheckedPut

A file that was never synchronized is only ever offered for deletion unchecked: nothing is deleted just because it has no record.

Put and Get of single files

sync-servers put css/site.css and get move the files and folders you name at once, through the same checks. When one of them changed on the other side, or is held back by the guard, the preview opens first so you can decide.

The preview

The preview lists only files with a difference; unchanged files are counted, never listed. Its summary line counts what will happen, such as Files: 37 will be updated, 169 will be skipped, 12 need a decision. Each row has a checkbox, an action and a status that says why, in a sentence:

Rows that start unchecked
RowWhy
ResolveChanged on both sides, or differs with no record. Choose an action first.
GuardedMatches a sensitive pattern such as .env; see the guard.
Never-synchronized deleteOffered by the delete option for a file with no record.
ProblemA name that cannot be used here: not valid on this system, a symbolic link that is not followed, or two names that differ only by case on a file system that cannot tell them apart. Problem rows never run.

You can change any row: check or uncheck it, or choose another action that the file can take. Put needs a local copy, Get a server copy, and Synchronized both.

Running a plan

Safety guards

Some plans stop before anything moves, with exit code 5: