Sync Files (zeysdk sync)
The sync command synchronizes local files with the ZeyOS server and handles bidirectional changes.
zeysdk sync [ASSET_PATH...] [options]
Parameters
| Parameter | Description | Required | Example |
|---|---|---|---|
ASSET_PATH | Specific asset paths to sync | No | services/backup.ixml |
Options
| Option | Description |
|---|---|
-f, --force | Skip the broad change-set confirmation; conflict choices may still prompt |
--verbose | Show detailed output |
--debug | Show detailed debug information |
--debug-log | Write debug output to .zeysdk/debug.log |
--resolve <strategy> | Conflict resolution strategy (mine, theirs, merge, or skip) |
--resolve-all | Apply the --resolve strategy to every conflict instead of only the first |
--no-resolve | Leave conflicts and their sync baselines untouched without prompting |
--break-lock | Replace the current sync lock after you verify its operation is no longer running |
--dry-run | Read and report planned changes without applying them |
--concurrency <number> | Maximum concurrent file operations (default: 10) |
-q, --quiet | Suppress progress indicators |
Process
-
Preparation
- Validates
.zeysdk/sync.json - Removes stale SDK-owned merge temporary files
- Acquires the project sync lock
- For a non-dry-run operation, cleans missing manifest entries and creates a rotating
sync.jsonbackup
- Validates
-
State Collection
- Scans local files and settings
- Fetches server state from the active instance
- Computes local, sync, and server hashes
-
Change Planning
- Builds local-to-server and server-to-local changes
- Detects deletes and conflicts
- Displays the planned synchronization result
-
Conflict Handling
- Prompts for conflict resolution when needed
- Applies
--resolveto the first conflict, or to every conflict when combined with--resolve-all - Leaves skipped and unresolved conflicts, including their common sync baseline, untouched
-
Apply Changes
- Pushes local changes to the server
- Pulls server changes to local files
- Updates sync state and manifest metadata
- Releases the sync lock
Locking
Sync uses .zeysdk/.sync.lock, shared with pull, push, rollout, and recover. Lock creation is atomic and release is tied to the acquiring owner's token. If another operation owns the lock, sync exits without applying changes. A stale lock is reclaimed automatically.
Use --break-lock only after confirming that the recorded process is no longer performing synchronization work. The lock is released from a finally path when sync succeeds, fails, or the user cancels a prompt.
Dry Run
--dry-run scans local files, reads server state, computes changes, and reports conflicts. It returns before conflict resolution and before any apply step, even when --resolve is also supplied. It does not apply the planned server updates or deletions, change project files, clean or update zeyos.app.json, update sync.json, or create a sync-state backup. When --debug-log is also supplied, the requested .zeysdk/debug.log is still written.
The command may still remove an SDK-owned zeysdk-sync-* merge temporary file older than one hour from the system temporary directory.
Status Indicators
| Symbol | Meaning |
|---|---|
+ | Created locally or added on server |
- | Deleted locally or deleted on server |
~ | Modified locally or modified on server |
! | Conflict |
<> | Property conflict |
-> | Local changes to be pushed |
<- | Server changes to be pulled |
Conflict Resolution
When conflicts are detected, sync displays content and property differences and offers these strategies:
| Strategy | Result |
|---|---|
mine | Use local content and metadata and send it to the server |
theirs | Request server content and write it locally |
merge | Open the configured comparison tool, then use the merged local file as the outgoing version |
skip | Do not apply the conflict and do not advance its sync baseline |
--resolve <strategy> resolves only the first conflict and skips the remaining conflicts. Add --resolve-all to apply the same strategy to every conflict. --resolve-all has no effect by itself.
--no-resolve suppresses conflict prompts and leaves every conflict and its baseline untouched; non-conflicting changes can still be applied. --force skips the broad change-set confirmation but does not select a conflict strategy, so conflicts still prompt unless --resolve or --no-resolve is present.
File Hashing and Synchronization
The sync process determines which files need to be synchronized by comparing stored hashes with hashes calculated from local files and hashes returned by the server. There is no timestamp or file-size pre-check before hashing.
The lastmodified value returned by the server is stored in sync.json for the synced item. It is not used to decide whether a file needs to be synchronized.
Use --verbose to see detailed comparison and processing output.
Examples
zeysdk sync
zeysdk sync weblets/dashboard.ixml
zeysdk sync -f
zeysdk sync --dry-run
zeysdk sync --resolve mine --resolve-all
zeysdk sync --no-resolve
Error Handling
| Error | Description | Resolution |
|---|---|---|
| Missing sync.json | No sync configuration | Run zeysdk link first |
| Invalid sync.json | Missing id/url | Re-link instance |
| Network error | Server unreachable | Check connection |
| Auth error | Invalid/expired token | Re-link application |
| Merge conflict | Unresolved changes | Choose a strategy, use --no-resolve, or rerun after manual reconciliation |
| Lock error | Sync lock already exists | Wait for current sync or use --break-lock |
| File system error | IO problems | Check permissions |
Notes
syncis bidirectional and can change both local files and server state--dry-runpreviews planned operations without changing project, manifest, server, or sync state- A non-dry-run sync creates a rotating backup of
sync.jsonbefore applying changes - On failure, automatic restore covers only
sync.json; it cannot undo local, manifest, or server changes already applied - Skipped and unresolved conflicts retain their previous sync baseline for a future reconciliation
lastmodifiedis stored for synced items but is not used to decide whether files changed
Best Practices
- Use
zeysdk comparebefore syncing when you expect conflicts - Use
--dry-runfor production or scripted workflows - Keep conflict resolution explicit with
--resolveand--resolve-allwhen running non-interactively - Use
zeysdk recover --listto inspect retained sync-state backups after an interrupted operation - Avoid
--break-lockunless a previous sync was interrupted and no sync process is active