Free Tools Pricing
Log in Sign up →
Docs CLI devsafe restore

devsafe restore

Decrypt and restore a git bundle from your user-owned storage back to your local machine. Includes a drift check to confirm the roundtrip is perfect. Paid

Usage

terminal
$ devsafe restore <repo-id> [--target <dir>] [--file <path>] [--to <time>]

The restore command downloads your encrypted git bundle from user-owned storage, decrypts it locally with your key, and rebuilds the repository. Your key never leaves your machine during this process.

Before restoring, DevSafe saves your current state as a "pre-restore" checkpoint. If something goes wrong, you can restore back to that checkpoint.

Flags

FlagDescriptionDefault
--target <dir>Stream a single-pass restore to a new directory instead of overwriting the current one.Current directory
--file <path>Restore a single file from the backup instead of the entire repository.All files
--to <time>Restore to a specific point in time. Accepts relative times like "1h ago" or absolute timestamps like "2026-04-29 14:00".Latest snapshot
--dry-runShow what would be restored without making any changes.Off

Restore to current directory

The simplest restore. This downloads your latest encrypted git bundle, decrypts it, and replaces the current repository contents. DevSafe saves a checkpoint first, so you can undo the restore if needed.

terminal
$ devsafe restore api-server
→ downloading bundle from user-owned storage...
→ decrypting with nonce-unique AEAD (AES-256-GCM)...
→ saving current state as "pre-restore" checkpoint...
→ unbundling git objects...
 restored api-server (247 objects, 18.3 MB)
 drift: 0 files (perfect roundtrip)

The drift check at the end compares every file in the restored repo against the original snapshot. A perfect roundtrip means 0 files changed. This proves that the backup, encryption, storage, download, decryption, and unbundle cycle preserved every byte.

Restore to a new directory

Use --target to stream the restore into a fresh directory. This is useful when you want to compare the backup against your current working tree, or when you need to recover without disturbing your current state.

terminal
$ devsafe restore api-server --target ~/recovered/api-server
→ creating ~/recovered/api-server...
→ downloading bundle from user-owned storage...
→ decrypting with nonce-unique AEAD (AES-256-GCM)...
→ streaming single-pass restore...
 restored to ~/recovered/api-server (247 objects, 18.3 MB)
 drift: 0 files (perfect roundtrip)

The --target flag performs a single-pass restore. DevSafe streams the decrypted bundle directly into the new directory without writing any temporary files to disk.

Restore a single file

If you only need one file back (say you accidentally deleted or overwrote it), use --file to restore just that file from the latest backup.

terminal
$ devsafe restore api-server --file src/config/database.go
→ locating src/config/database.go in latest snapshot...
→ decrypting bundle...
 restored src/config/database.go (2.1 KB)

You can combine --file with --to to pull a specific file from a specific point in time.

Restore to a specific time

The --to flag lets you roll back to any snapshot. DevSafe finds the closest snapshot at or before the time you specify.

Relative time

terminal
$ devsafe restore api-server --to "1h ago"
→ resolving snapshot at 13:23:08...
→ saving current state as "pre-restore" checkpoint...
→ decrypting with nonce-unique AEAD (AES-256-GCM)...
 restored to snapshot from 13:23:08 (12 files changed, 0 conflicts)
 drift: 0 files (perfect roundtrip)

Absolute timestamp

terminal
$ devsafe restore api-server --to "2026-04-29 14:00"
→ resolving snapshot at 2026-04-29 14:00:00...
→ found snapshot from 2026-04-29 13:58:42 (closest match)
→ saving current state as "pre-restore" checkpoint...
→ decrypting with nonce-unique AEAD (AES-256-GCM)...
 restored to snapshot from 2026-04-29 13:58:42
 drift: 0 files (perfect roundtrip)

If no snapshot exists at or before the requested time, DevSafe will tell you and show the earliest available snapshot.

The drift check

Every restore ends with a drift check. DevSafe compares the restored files byte-for-byte against the original snapshot metadata. This is how you know the entire cycle worked: backup, nonce-unique AEAD encryption, upload to user-owned storage, download, decryption, and unbundle.

terminal
# Perfect roundtrip
 drift: 0 files (perfect roundtrip)

# Working tree had local changes since the snapshot
 drift: 3 files changed since snapshot
  modified  src/main.go
  modified  go.sum
  added     src/config/new.go
Drift is not an error.

Drift means files have changed since the snapshot, not that the restore failed. If you restore to "1h ago" and then kept working, the drift shows what you changed in that hour.

Combined examples

terminal
# Restore a single file from 2 hours ago
$ devsafe restore api-server --file src/main.go --to "2h ago"

# Restore to a new directory from a specific date
$ devsafe restore api-server --target ~/compare/api-old --to "2026-04-29 14:00"

# Preview what would be restored without changing anything
$ devsafe restore api-server --dry-run --to "1h ago"