Capture and Restore a Filesystem Tree
This workflow turns one directory into a verified immutable graph, gives it a durable name, and restores the exact graph later.
Import and retain the tree
Section titled “Import and retain the tree”$ casita --repository ./cache import ./project --root projects/demoDirectories select the filesystem importer automatically. The command prints the resulting casita.directory.v1 key. The named root
retains that directory and every object reachable through its verified links.
Imports normally reuse an earlier file result when device, inode, size, and timestamps are unchanged. Force every file to be reread when that assumption does not suit the source:
$ casita --repository ./cache import ./project \ --root projects/demo --filesystem-rehashFilesystemImport publishes the tree and its root in one operation. Use
FilesystemImport::new(...).reread(true) when every regular file must be read and hashed again.
use casita::{Repository, RootName};
let repository = Repository::local("./cache").await?;let root = RootName::try_from("projects/demo")?;let tree = repository.import(casita::import::FilesystemImport::new("./project", root)).await?;
println!("{tree}");Inspect the graph
Section titled “Inspect the graph”$ casita --repository ./cache root ls projects$ casita --repository ./cache object show casita.directory.v1:...$ casita --repository ./cache tree list casita.directory.v1:...$ casita --repository ./cache cat casita.blob.v1:...object show exposes the logical key, physical payload, exact forward links,
and closure status. tree list interprets a canonical directory; cat writes
a blob’s bytes to standard output.
Restore safely
Section titled “Restore safely”$ casita --repository ./cache checkout casita.directory.v1:... ./restoredThe destination must be absent or empty. Checkout first builds a sibling staging directory on the destination filesystem, then renames it into place. It either recreates the graph’s exact names or fails without a partial checkout; this catches case-folding, Unicode-normalization, and native-name conflicts on the actual target filesystem. Checkout uses handle-relative writes so a path component swapped for a symlink during materialization cannot redirect writes outside the destination. Stored symlinks are recreated rather than followed.
Successful checkout creates an auto/checkout/... root by default. Use
--no-root only when another root already retains the graph or the restored
copy is intentionally disposable.
Release data deliberately
Section titled “Release data deliberately”$ casita --repository ./cache root rm projects/demo$ casita --repository ./cache gc --dry-run$ casita --repository ./cache gc$ casita --repository ./cache fsckRemoving a name only makes its unshared closure eligible for collection. The dry run shows what a real collection would remove.
Read Imports for cache assumptions, Roots and Retention for liveness, and the CLI Reference for exact syntax.