Skip to content

forest

git-like data management for arbitrary data trees.

Git tracks code in .git/; forest tracks large data — local layout plus remote sync — in .forest/. It borrows git's mental model and verbs (checkout, status, push, pull, remote, a HEAD-style pointer) so your git intuition carries over, but the two domains never overlap and neither requires the other.

~/my-repo
$ forest init                                     # the nameless .forest/
$ forest checkout demo                            # create if absent, activate
$ forest remote add origin s3://my-bucket/prefix  # any rclone URL
$ forest add raw ./data/raw                       # register stage, bind path
$ forest push                                     # sync every bound stage
✓ raw → origin — data tracked, git untouched

Forest is domain-agnostic and self-contained: it manages any data tree, knows nothing about what the data means, and depends on no other project. It moves files and tracks their sync state; it does not validate or interpret their contents. No config files are hand-written — onboarding is the five commands above.

  • Learn it step by step


    Seven short chapters from forest init to a fully synced repo — every output block captured from a real session, runnable without credentials, ending with the dogfood setup this repo itself runs on.

    Start the tutorial

  • Up and running in minutes


    Install with pip, put rclone on your PATH, and onboard a repo with five commands.

    Installation

  • A fixed-depth model


    workspace → checkout → stage → unit → files. No arbitrary nesting, O(1) checkout switching, data never moves.

    The data model

  • Reference, when you need it


    Every command, both config files, and all environment variables in one place.

    CLI reference

Why forest?

  • Your git intuition carries over. Checkouts behave like branches you stay rooted in; push/pull/status/diff work against a named remote.
  • Data never moves on switch. Switching checkouts is an O(1) pointer rewrite — no file shuffling.
  • Real filenames. Data lives under real paths, not a content-addressed blob store.
  • Safe by default. Every transfer is verified against the remote before it's recorded, and per-file SHA-256 hashes catch same-size edits. Pull refuses to clobber unpushed local changes; push refuses to clobber a remote that changed out-of-band — --force is always an explicit decision.
  • Quiet by default. Logging is opt-in via environment variables; forest sends nothing anywhere unless configured.

See it in production

The forest repository manages its own examples/ tree with forest — a live demonstration that .forest/ and .git/ coexist without overlapping. Read the dogfood walkthrough →