Clone from a Forge or peer, then sync¶
This guide gets a repository onto your machine and keeps it in step with everyone else. The headline:
tovio sync does push and pull in one command, and when your history and a teammate's have
diverged, tovio sync reconciles the two on the lane — a clean merge, or a tracked conflict —
deterministically and without a force-push, so neither side's work is ever left off-lane. An exchange
can still be refused by authorization, protected-ref, quota, object-closure, state, or transport gates.
Networked clone and sync are built
Networked clone and tovio sync (push and pull over native TLS and HTTP-framed sync, sparse
path-scope, N-replica CRDT convergence) are built and tested, and opportunistic auto-sync is on by
default. Production binaries passed the distinct-Docker-host exercise under a real operator CA.
Public-release, broader HA/load, hosted parity, and external evidence remain Phase 5 gates.
flowchart LR
C["tovio clone"] --> R[("local repo")]
R -. "tovio sync" .-> F(("Forge / peers"))
F -. "diverged tips reconcile on-lane" .-> R
More diagrams for the full team collaboration flow: Team workflows.
Clone a repository¶
tovio clone takes three things: the relay, the repository id, and the directory to create. The relay
is either a hosted Forge (https://host, trusted through public PKI) or a native relay (host:port, the
address tovio serve prints — port 7743 by default), which needs the relay's pinned certificate.
$ tovio clone https://forge.example.dev <repo-id> repo
✓ Cloned 1204 objects from https://forge.example.dev into repo
A clone with no filter flags is complete: full history, every object, fully usable offline. Three
composable axes narrow it — which subtree (--sparse "src/**", repeatable), how much history
(--depth 50), and which content (--blobless, or --blob-limit <bytes> to skip only large files):
Any filtered clone is promisor-backed: the objects it omitted are not lost — a read of one backfills
lazily from the origin, re-hashed on arrival. tovio fetch --deepen <n> extends a shallow history and
tovio fetch --complete fattens the repository back to a complete, offline-sovereign closure.
Missing decryption clearance does not by itself block an authorized clone
Policy-protected files arrive as ciphertext and are decrypted on access only if your identity's
attributes satisfy their policy. You can clone a repository in full and still be unable to read the
protected payloads in it. If repository discovery and transfer are otherwise authorized, lacking a usable
recipient key leaves those paths encrypted rather than granting plaintext. Repository authorization,
object disclosure, quota, closure verification, and transport can still refuse the clone. To learn what's
gating a file you can't read, use tovio access check.
Sync your work¶
tovio sync is the everyday command for sharing and receiving changes. With no arguments it uses the
origin saved when you cloned; it is built for both humans and always-on agents.
That single line is push and pull together: it sent your local objects and received four, and it merged
the lane refs. You don't run push then pull — sync is the native verb.
One direction only¶
If you genuinely want just one direction, restrict it:
A one-way --push won't clobber a diverged remote
tovio sync --push skips the pull, so it can't reconcile. If the remote lane has moved on and
diverged from your tip, the push is refused (TVO-SYNC-006, "Push refused: the remote lane has
diverged from your local tip") before anything is uploaded, rather than orphaning the remote tip — run
a full tovio sync to reconcile on-lane first, then the push fast-forwards.
Coming from Git
tovio push and tovio pull are the one-direction primitives behind sync, kept for Git muscle
memory. Typed bare, they print a hint for migrants; with a relay and repository id they push or pull.
The native equivalent of both is just tovio sync — one command, both directions.
Auto-sync keeps you current between syncs¶
You will run tovio sync less often than you expect, because opportunistic auto-sync is on by
default. After a history- or lane-advancing command succeeds — commit, land, switch, tag,
cherry-pick, revert, rebase — TOVIO runs one throttled sync (at most once per sync.auto.interval
seconds, default 120). It is deliberately conservative:
- It always pulls, but never materializes over a dirty working copy — with uncommitted edits it skips the round rather than risk them.
- It keeps your lane current with its upstream (the lane it will land onto, defaulting to the lane you
branched from;
tovio autosync upstream --set <lane>retargets it) by folding the upstream in only when that merge is conflict-free; a merge that would conflict is left for a deliberatetovio land. A protected lane is never auto-advanced, and this fold runs only on a complete checkout — a sparse or partial clone integrates its upstream through an explicittovio land. - Push is consent-gated. The default
sync.auto.push = sharedpushes only the current lane, and only after you have published that lane once yourself — your first manualtovio syncis the act of consent. Protected lanes are never auto-pushed. - It is never fatal and never noisy: an offline or locked repository is a silent skip, and the primary
command's exit code and
--jsonoutput are untouched.
Turn it off for one command with the global --no-sync flag, for a shell with TOVIO_NO_SYNC, or for the
repository with tovio config set sync.auto off. To stay current while idle, run the continuous
companion in a spare terminal:
$ tovio sync --watch
✓ watching origin — syncing every 120s (Ctrl-C to stop)
✓ auto-synced with origin (↓ 5 object(s), merged upstream)
--interval <secs> overrides the poll interval and --once runs a single poll for scripts.
Divergence reconciles on the lane¶
This is the part that feels different from Git. When you and a teammate both advanced the same
unprotected lane offline, an interactive tovio sync doesn't reject your push or pick a winner and
strand the other tip — it reconciles the two on the lane. It runs the same merge engine tovio land
uses: if the two sides merge cleanly, the lane advances to a two-parent merge commit; if they can't,
the lane advances to a two-parent commit that carries the conflict as data. Either way both tips
become parents, so neither line of work is ever left off-lane. There's no diverged-history error and no
force-push.
$ tovio sync
✓ Synced with forge.example.dev:7743 (received 1 object(s), sent 1; 1 ref(s) merged)
✓ reconciled divergent lane `main` on-lane (clean merge, blake3:7yq2…)
If the two sides touched the same lines, the reconciliation carries the conflict — on the lane, as data:
$ tovio sync
✓ Synced with forge.example.dev:7743 (received 1 object(s), sent 1; 1 ref(s) merged)
🔒 reconciled divergent lane `main` on-lane with 1 conflict(s) to resolve (blake3:7yq2…)
conflict src/integrations/auth/oauth.ts
Run tovio conflicts to see it and tovio resolve to settle it. Only an interactive tovio sync or
tovio pull builds this reconciliation commit; background auto-sync adopts refs and isolates, and leaves
a genuine divergence for your next manual sync.
Read this as relief, not a warning
In Git, "your branch and the remote have diverged" is the start of a stressful afternoon. In TOVIO
it's a status line: your work and theirs are combined into one commit on the lane, or held together
as a tracked conflict — never a silently dropped tip. The reconciliation commit has a
deterministic identity, so if a teammate reconciles the same divergence independently they land the
byte-identical commit and everyone converges — no merge-of-merges. Authorization and protected-lane
requirements still apply, and require_review lanes reconcile through their proposal/review path
rather than auto-reconciling here.
When a teammate's change still has conflicts¶
Conflicts are data in TOVIO, so a reachable conflict object transfers like any
other addressed object. But sync will not drop someone else's unresolved conflict markers into your
working tree if your change builds on top of theirs. That would break your build, so the materialize step
is gated (TVO-CONFLICT-004) — the objects still download; only the materialization is refused.
$ tovio sync
✗ Cannot pull chg:002 as a dependency: 1 unresolved conflict(s)
Change chg:002 has 1 unresolved conflict object(s); materializing it into the working tree as a
dependency you build on top of would break the build. The objects still downloaded — only the
materialization is refused.
~ src/integrations/auth/oauth.ts
Notify the author:
tovio change notify chg:002
Build against the last-known-clean version:
tovio materialize --isolate
List the conflicted paths:
tovio status --conflicts
[TVO-CONFLICT-004]
You have two clean choices:
- Wait for Bob to resolve.
tovio change notify chg:002records a local, never-synced notify intent for the change;tovio change watch chg:002 --remote <forge>polls the Forge's event feed and returns when the change resolves or lands. - Isolate.
tovio sync --isolate(or, with the objects already downloaded,tovio materialize --isolate) materializes the conflicted paths at their last-known-clean version so your tree builds, and pins them sotovio statusflags the isolated build. The conflict stays flagged, and the pinned path re-materializes on its own the next time a sync transfers Bob's resolution — no command to run.
A conflict in your own stack never blocks you. This gate is only the boundary where a teammate's unresolved conflict would land in your build.
If the relay is unreachable¶
A relay you can't reach is reported, never destructive. The transport fails before any ref or working-copy mutation, so your local work is untouched and your next sync picks up where this one left off.
$ tovio sync
✗ Sync failed: connection refused
The connection, TLS handshake, or object transfer did not complete.
Check the address, that `tovio serve` is running, and that the relay cert matches (--cert)
[TVO-SYNC-003]
Recap¶
tovio clone <relay> <repo-id> <dir>— complete by default;--sparse,--depth,--blobless/--blob-limitnarrow it into a promisor-backed clone that backfills on read. Protected files arrive encrypted and stay that way without clearance.tovio sync— push and pull in one; a divergence reconciles on the lane into a merge-or-conflict commit, so there's no "diverged", no "rejected", and no off-lane orphan.- Auto-sync is on by default: pull after every advancing command, conflict-free-only upstream
integration, consent-gated push;
--no-sync/TOVIO_NO_SYNC/sync.auto offturn it off;tovio sync --watchkeeps syncing while idle. tovio sync --push/--pull— one direction when you want it.tovio sync --isolate— build past a teammate's unresolved conflict at the last clean version.
Where to next¶
- Ready to get a change reviewed? See propose and review.
- Landing onto a guarded lane? See lane protection.
- Carrying big assets through sync? See large binaries.
Last reviewed September 9, 2026
Suggest an improvement to this page Not for security reports — see disclosure