calsync docs

How a sync decides

calsync keeps no database. Each run it reads your calendars and works out what is missing, changed or left over.

One run

  1. List. It reads each calendar for the next 120 days. Events that already ended are ignored.
  2. Find the real events. A real event is one calsync did not make. Declined events and cancelled events are not real events, so they are skipped.
  3. Work out the wanted copies. Each writable calendar should hold one copy of every real event from every other calendar, apart from the exceptions below.
  4. Compare. It finds the copies already there by their private tag. It creates the missing ones, updates the changed ones and deletes copies whose original is gone, declined or cancelled.

The tag is the state

Every copy carries a private tag that only calsync reads. The tag is how calsync finds its own work next time. Nothing else is stored, so there is nothing to migrate and nothing to lose. calsync only ever edits or deletes events that have its tag.

Exceptions

What a copy looks like

What stops a run

A calendar does not load
That calendar is left alone this run. Nothing is deleted because of it.
A very large delete
If a run would delete more than half of a calendar's copies, and more than 10, it stops for that calendar and waits. If the delete is what you meant, run calsync run --force.
Preview
Preview changes on the page, or calsync run --dry-run, goes through the same steps and changes nothing.