Clone only part of a repository

Sparse, blobless, size-limited, shallow, and attachment-free clones.

Written By Dustin

Last updated 22 minutes ago

tovio clone <remote> <repo> <dir> --sparse 'src/**' --sparse 'docs/**'tovio clone <remote> <repo> <dir> --bloblesstovio clone <remote> <repo> <dir> --blob-limit 10000000tovio clone <remote> <repo> <dir> --depth 50tovio clone <remote> <repo> <dir> --no-attachments
FlagWhat it omits
--sparse <glob>Everything outside these paths. Repeatable.
--bloblessAll file content. History and trees arrive; contents backfill on read.
--blob-limit <bytes>File content larger than this many bytes. Smaller files still clone. The practical option for a repository with large binaries.
--depth <n>Commits older than the tip plus n.
--no-attachmentsThe semantic and behavioral closure, fetched later on demand.

What cannot be combined

A path scope and an object filter are two different partial modes, and one would silently win over the other, so the CLI refuses the combination rather than guessing:

  • --sparse cannot be combined with --blobless, --blob-limit, --depth, or --no-attachments.
  • --blobless and --blob-limit cannot be combined with each other.
  • --blobless or --blob-limit together with --depth is fine — a filter and a history boundary are independent.

Two different kinds of partial

This distinction decides which recovery commands work on your clone, so it is worth getting straight.

ModeWhat the clone becomes
--blobless, --blob-limit, --depth, --no-attachmentsPromisor-backed. The omitted objects are recorded as promises against the remote you cloned from, and a read that needs one fetches it lazily.
--sparsePath-scoped. Objects outside the scope were never requested, and the working-copy cone is seeded from the same globs. It is not promisor-backed.

What a promisor-backed clone depends on

Lazy backfill needs the remote. If it is unreachable, or no longer holds the object, the read fails closed with TVO-SYNC-005 rather than returning empty or partial bytes. Nothing local is lost — a promisor is trusted for availability, never for content, so a failure there is a recoverable sync error rather than corruption.

Operations that need the full closure refuse up front instead of silently pulling the whole repository as a side effect. tovio git export is the clearest example — it tells you to fatten first.

Filling in later

tovio fetch --deepen 100tovio fetch --complete

Both axes only ever enlarge what you hold, so staying partial never loses data, and --complete turns a promisor-backed clone into a full one.

tovio fetch only applies to a promisor-backed clone. On a --sparse clone it refuses with “this repository is already complete”, because from the object store's point of view it is — the out-of-scope objects were never promised. Widening a sparse clone means re-cloning with a broader scope, or without one.

Do not use these for an exit copy

If you are cloning to leave, take a complete clone. If you already have a promisor-backed one, run tovio fetch --complete and then tovio fsck before treating it as your copy of record. If you have a sparse one, clone again without --sparse — there is no in-place way to widen it.