Skip to content

2. Checkouts

A checkout is a named data view registered in the workspace — like a git branch you stay rooted in. Switching is an O(1) pointer rewrite; data never moves.

Our survey gets a checkout named survey:

forest checkout survey
Created and switched to new checkout 'survey'.
Run: forest remote add NAME URL

Bare forest checkout <name> switches to the checkout — and when the name isn't registered yet (like just now), it creates, registers, and activates it first. The explicit forms exist too:

forest checkout create <name>    # create without the implicit fallback
forest checkout list             # what's registered
forest checkout current          # what's active (the HEAD pointer)
forest checkout remove <name>    # deregister; --yes skips the prompt

The HEAD pointer

The active checkout name lives in .forest/HEAD — one of the gitignored files from chapter 1, because which checkout you have active is your business, not the repo's:

cat .forest/HEAD
survey

list marks the active checkout with *, and current prints just the name (handy in scripts):

forest checkout list
* survey

Switching is cheap — try it

Create a second checkout, look around, switch back, and clean it up:

forest checkout autumn-archive
forest checkout list
Created and switched to new checkout 'autumn-archive'.
Run: forest remote add NAME URL
* autumn-archive
  survey
forest checkout survey
forest checkout remove autumn-archive --yes
Switched to checkout 'survey'.
Run: forest remote add NAME URL
Removed checkout 'autumn-archive'.

Nothing under data/ would have moved during any of that — switching only rewrites .forest/HEAD.

Typo'd a checkout name?

Auto-create means forest checkout syrvey quietly creates a checkout called syrvey. The undo is exactly what you just ran: forest checkout remove syrvey --yes (removal is metadata-only; it never touches data).

What just happened on disk

.forest/
  config.yaml          # committed — now lists 'survey' under checkouts{}
  HEAD                 # gitignored — contains: survey
  checkouts/
    survey/
      forest.yaml      # committed — the checkout's shared config
      local.yaml       # gitignored — your machine's local half
      sync_state.json  # gitignored — your machine's push/pull history

The checkout's shared config is nearly empty so far:

.forest/checkouts/survey/forest.yaml
project: survey
remotes: {}
stages: {}

Recap: a checkout is a registered, named data view; HEAD points at the active one; switching is an O(1) pointer rewrite.

Next: give the checkout some structure — stages & binding.