When an operation is interrupted
Computers crash, laptops run out of battery, and disks fill up. Synck is built so that an interruption at any moment leaves the repository in one of two states: the operation either did not happen, or it can be finished. You should never end up with half a commit, or with history that refers to content that is not there.
This page explains how that works, and what, if anything, you need to do.
The one rule
Leave .synck alone, and run Synck again. Do not delete files in .synck,
restore an older copy of it on top, or “clean up” its temporary directories. Synck
keeps the records it needs to recover in there.
Two stages: content first, then history
Every write follows the same order:
1. store new content objects written and flushed to disk
│
▼
2. accept the commit one database transaction: the point of no return
│
▼
3. bring indexes up to date repository order, current-state tables, history index
- Interrupted during stage 1: nothing is in the history. At worst some
stored objects are not referenced by anything. They are harmless and
synck gccan remove them. History can never point at content that is not there, because content is always stored first. - Interrupted during stage 2: the database transaction either committed or it did not. There is no partial commit.
- Interrupted during stage 3: the commit is accepted and permanently in the history. Only the bookkeeping after it is pending.
Repositories with a checkout
In a repository with a checkout, recovery is automatic. Operations that change
both the history and your files, such as mv, revert, recover,
restore-tree, commit --batch and changes to a checkout’s selection, first
write an intent record in
.synck that describes exactly what they are going to do. If one is
interrupted, the next Synck command you run in that repository finds the
record, finishes the operation, and then does what you asked:
$ synck status # first command after a crash
nothing to commit, working tree clean
If the state on disk does not match any valid point of the interrupted operation, for example because files were changed by hand in the meantime, Synck does not guess. It stops and reports exactly what is inconsistent. Resolve that, or restore from a backup, before continuing.
Batch commits
synck commit --batch records several commits. If it is interrupted, the
commits that were already accepted stay accepted. Synck continues forward. It
never pretends to roll accepted commits back. The batch resumes automatically
on the next command. If you changed one of its remaining files in the meantime,
it finishes the accepted part and leaves the rest as ordinary uncommitted
changes.
When an interrupted command prints commit IDs before its error, those commits
are in the history. Check synck log before you try anything again.
Writes with synck repository
The synck repository write commands, such as save-file and append-chat,
recover only when you ask. Reading a repository never changes it, so a write
that was interrupted in stage 3 stays pending until you finish it:
$ synck repository save-file 01a174b7-8f4e-76f1-8ac4-440db922fb52 proposal-v3.txt --path launch-continued
synck: commit sha256:2776…edf1 was accepted; local recovery is pending: ...
$ synck repository finalize launch-continued
{"finalized":"launch-continued","schema_version":1}
Do not run the original command again. It would record the change a second
time, as a duplicate file version or a duplicate message. Until you finalize,
synck repository verify reports that sequencing is incomplete.
Copies and archives
synck archive, synck repository archive, synck repository import and the
export commands all write to a new
destination. They build the result privately and publish it only once it is
complete and verified:
- Interrupted before publishing: the destination does not exist. A killed
process may leave a private staging directory beside it, with a name
starting with
.synck-. It is safe to delete. Synck never resumes from it. - Published, but the final flush to disk failed: Synck reports this case explicitly. The result is visible but might not survive a crash. Verify it, and repeat the copy to a new destination if in doubt. Do not assume nothing was created.
The source is never modified by a copy, so a failed copy leaves your previous copies exactly as they were.
“Repository busy”
Each Synck command holds an exclusive lock on the repository while it runs. A second command started at the same time fails immediately rather than waiting:
synck: repository busy
This is not damage. Wait for the other command to finish (it may be a script, an editor integration or another terminal) and try again. If you are sure no other Synck process is running, the lock was released when the previous process ended. Locks do not survive their process, so there is nothing to delete.
Disk full
Running out of space is just another interruption. The operation stops at
one of the stages above and recovers the same way. Free some space, then run the
next command or finalize. Do not free space by deleting files in .synck.
To find out what history is costing you, use synck storage.