Skip to main content
Copy snapshots from another repository into this one — to seed a new repository, migrate to a different storage backend, or promote local snapshots into a remote repository. A copy preserves history. The copied snapshots keep their original creation times, tags, source identity and file metadata, so the destination looks like it always held them rather than like you re-ran a backup today.

Usage

Both repositories must already exist. copy never creates the destination: choosing key slots and encryption is a decision for cloudstic init, not a side effect of a migration.

Configuring the two repositories

The destination is configured exactly as for every other command — -store, -profile, -password, and the rest. The source repository gets a parallel set of -from-* flags that mirror every flag which locates or unlocks a repository:
The -from-* flags read no environment variables. CLOUDSTIC_PASSWORD and its siblings configure the destination only.This is deliberate. An ambient variable means “the repository I am operating on”, and silently applying one to both repositories of a two-repository command is how you unlock the wrong one — or believe you did.
For non-interactive use, name the source with -from-profile. A profile entry may carry env:// secret references like any other, which keeps credentials out of your command line:
The source must always be named explicitly. Unlike -store, it has no default.

Arguments

string
Optional. Copy only the named source snapshots. Each can be a full hash, any unambiguous prefix, or latest. Filters still apply on top, narrowing the set further.With no snapshot arguments, every source snapshot is selected.

Options

string
Source repository URI, in the same form as -store.
string
Source repository from a named profile. The profile supplies its own store, credentials and secret references.
boolean
default:"false"
Resolve the selection and report what would be copied, without writing anything.
string
Copy only snapshots of this source URI (for example local:./Documents, or a bare type such as gdrive).
string
Copy only snapshots of this account.
string
Copy only snapshots carrying this tag. Repeat the flag to require several tags.
string
Copy only snapshots created at or after this time. Accepts a date (2026-04-01) or an RFC 3339 timestamp (2026-04-01T20:15:03Z).
boolean
default:"false"
Allow copying snapshots that were themselves produced by an earlier copy, re-stamping their provenance to the immediate source.
The full -from-* set mirrors the repository flags: -from-s3-endpoint, -from-s3-region, -from-s3-access-key, -from-s3-secret-key, -from-b2-key-id, -from-b2-app-key, -from-store-sftp-password, -from-store-sftp-key, -from-store-sftp-known-hosts, -from-store-sftp-insecure, -from-encryption-key, -from-recovery-key, -from-kms-key-arn, -from-kms-region, -from-kms-endpoint, -from-disable-packfile and -from-prompt. Run cloudstic copy -h for the authoritative list.

Examples

Output

Both repositories are named before anything is written, because a mistyped destination is the one mistake a rerun cannot undo:
Use -json for a machine-readable result.

Rerunning is safe

Each copied snapshot records where it came from, so a second run skips what it already copied without re-reading the source:
The same mechanism makes an interrupted copy cheap to resume. Rerun the command and only the unfinished work is repeated — every object already transferred is recognised and skipped.

What is preserved

Sequence numbers record write order within a repository, so they cannot carry across — the source’s numbers would collide with history the destination already has. Snapshot hashes change for the reason described below.

Cost

Copying is much more expensive than an incremental backup, and it is worth understanding why before starting one over a metered link. Every object reference in a repository is derived from that repository’s encryption key. Nothing can be moved verbatim, so each object in the selected snapshots is read and decrypted through the source, then re-encrypted and written to the destination under a new name. Two things keep this affordable:
  • Deduplication still applies. Data the destination already holds is recognised and skipped, so copying into a repository that shares content with the source is far cheaper than copying into an empty one.
  • Repeated history is not re-read. Copying a long run of snapshots costs roughly one repository, not one repository per snapshot, because snapshots that share files share the work.
The source and destination need not share a password, key slots, or encryption at all. Copying between an encrypted and an unencrypted repository works in either direction.

Interaction with retention

A copy re-imports any selected snapshot the destination does not currently have — including one the destination deliberately forgot. For a scheduled copy, pass -since with the previous run’s start time so that destination retention is not undone on every run:
Otherwise, apply retention to the destination after the copy rather than before it.

Copying a repository into itself

copy refuses this. It is not a harmless no-op: each source snapshot would be rewritten as a new snapshot carrying provenance, so the history would double. No data would be duplicated, but retention grouping and every snapshot count would be wrong afterwards. The check does not rely on you spelling the two locations identically — the same repository reached through a symlink, a bind mount, or one bucket under two endpoints is still detected.

Access requirements

The source is only ever read, so read-only credentials are sufficient there. This makes it safe to copy from a repository you do not own or do not want to risk modifying. If the source permits it, copy also places a shared lock there to prevent a concurrent prune from removing objects mid-copy. When the source refuses the write, the copy proceeds without that protection. A lock already held by another operation still stops the copy, because that means objects are actively being collected.

Verifying the result

Copied snapshots are ordinary snapshots of the destination afterwards. Verify them the same way you would any others:

See Also