Skip to content

06 Remotes And Recovery

repository objects / packs immutable
SQLite commits / segments/files immutable
HEAD / refs/** mutable transactional metadata

Immutable data can be content-verified and retried. A branch ref is the publication point that makes a history visible, so it requires compare-and-swap (CAS).

  1. Publish SQLite commits, segments, and pages.
  2. Publish external payload bytes.
  3. Publish repository objects or pack/index.
  4. CAS the destination branch against the value observed at start.

If CAS fails, the remote may retain unreachable immutable data while its branch still names a complete old history. Publishing the ref first would expose a commit with missing dependencies and is forbidden. Force only relaxes fast-forward policy; it does not remove expected-value CAS.

Fetch downloads the selected graph and updates refs/remotes/<remote>/<branch> with expected state. It does not move the current branch, modify the index, merge, or materialize. Metadata can arrive before all historical pages or payload bytes; later reads may hydrate lazily.

Pull is exactly:

fetch -> merge plan -> apply

It inherits fast-forward, three-way, conflicts, stale checks, materialization, and handle rules.

Clone initializes a new repository, configures the remote, obtains a stable ref and immutable dependencies, establishes tracking/upstream, then checks out. It does not silently overwrite a non-empty destination.

When a CAS request was sent but its acknowledgement is lost, the server may have rejected or committed it. Do not publish a different successor blindly. Read the remote ref and reconcile:

  • expected new value means success;
  • unchanged old value means known failure;
  • another value means concurrency/divergence and requires fetch plus a new plan.

Timeout and cancellation also only guarantee safe boundaries. Cancellation after request dispatch does not prove the server did nothing.

Failure pointPossible residueAuthority
private add backuptemp fileworktree and old index
storage commit before indexunreachable storage/blobold index/ref
tree/commit before refunreachable objectsold ref
ref before reflog appendnew branch, missing reflog lineref and object graph
multi-path checkoutbackups or partial restorationcanonical repository state plus status
active mergestages, journal, candidateindex and merge journal
remote immutable upload before CAS failureunreachable remote dataremote ref

Reads validate object IDs, expected storage commit hashes, and payload content hash/size. Corruption must be reported; a missing page cannot be synthesized as zero and a missing payload is not empty.

DomainRootsRemoves
SQLite storage GCindex, heads, branches, merge state, remote refs, tagsunreachable storage data
payload pruneindex and reachable external pointersunreachable store/files bytes
repository object GCobject graphno public loose-object GC in 1.0

Recovery order: stop writes, close affected SQLite handles, inspect status --json, finish or abort an active merge from its journal, reconcile uncertain remote refs, repair verified missing content, and only then clean data proven unreachable.