Skip to content

Tutorial

One path from an empty folder to push, status and pull. The remote is a local directory, so you need no cloud account. S3 and SFTP remotes work the same way.

You need forest (installation) and a current rclone on your PATH.

Sample data

mkdir -p ~/forest-remote ~/field-notes/data/raw/plot-01 ~/field-notes/data/raw/plot-02 ~/field-notes/data/processed
cd ~/field-notes
printf 'hour,temp\n9,14.2\n' > data/raw/plot-01/temps.csv
printf 'moss on north side\n' > data/raw/plot-01/notes.txt
printf 'hour,temp\n9,13.8\n' > data/raw/plot-02/temps.csv
printf 'plot,mean\n1,14.2\n2,13.8\n' > data/processed/summary.csv

Set up

$ forest init
Initialized empty forest workspace in ~/field-notes/.forest

Next steps:
  1. Run 'forest remote add <name> <url>' to configure a remote
  2. Run 'forest checkout create <name>' to create your first checkout
  3. Run 'forest add <stage> <path>' to register a stage and bind local data
$ forest remote add origin ~/forest-remote
Added remote 'origin' -> ~/forest-remote
$ forest remote use origin
Remote for new checkouts set to 'origin'.
$ forest checkout survey
Created and switched to new checkout 'survey'.
$ forest add raw ./data/raw
Added stage 'raw' -> data/raw
$ forest add processed ./data/processed --direction push
Added stage 'processed' -> data/processed

Give the remote an absolute path. A relative one is accepted by remote add but fails later at push.

Each subdirectory of data/raw is one unit. To make processed a single unit, add sync_by: directory under it in .forest/checkouts/survey/forest.yaml:

  processed:
    remote_path: survey/processed
    sync_by: directory
    direction: push

processed is now a single unit and only ever pushed. Stages covers these options.

Push and check

$ forest push
Transferred: 36 B, 2 files
PUSH raw/plot-01  2 files, 36 B -> origin
Transferred: 17 B, 1 files
PUSH raw/plot-02  1 files, 17 B -> origin
Transferred: 24 B, 1 files
PUSH processed/processed  1 files, 24 B -> origin
$ forest status
synced:origin  raw/plot-01/notes.txt  matches remote
synced:origin  raw/plot-01/temps.csv  matches remote
synced:origin  raw/plot-02/temps.csv  matches remote
synced:origin  processed/summary.csv  matches remote
$ find ~/forest-remote -type f | sort
~/forest-remote/survey/processed/summary.csv
~/forest-remote/survey/raw/plot-01/notes.txt
~/forest-remote/survey/raw/plot-01/temps.csv
~/forest-remote/survey/raw/plot-02/temps.csv

A bare push or pull covers every bound stage whose direction allows it, so a bare pull here prints Skipping stage 'processed' (direction: push). status compares live remote files and transfers nothing. The CLI reference lists every status row.

On a machine where rclone has no config yet, each transfer also prints Config file ... not found - using defaults. Running rclone config touch once silences it.

Change a file

$ echo '10,15.1' >> data/raw/plot-02/temps.csv
$ forest diff
modified  raw/plot-02/temps.csv
$ forest status --incomplete
local-changed:origin  raw/plot-02/temps.csv  differs from remote
$ forest push raw/plot-02
Transferred: 25 B, 1 files
PUSH raw/plot-02  1 files, 25 B -> origin
$ forest push
SKIP raw/plot-01  already synced to origin
SKIP raw/plot-02  already synced to origin
SKIP processed/processed  already synced to origin

diff compares against the last push, and status compares against the remote. --incomplete hides synced rows.

Pull somewhere else

-C PATH runs forest as if it were started in PATH. This sets up a second workspace and pulls into it:

mkdir ~/laptop
forest -C ~/laptop init
forest -C ~/laptop remote add origin ~/forest-remote
forest -C ~/laptop remote use origin
forest -C ~/laptop checkout survey
forest -C ~/laptop add raw ./data/raw
$ forest -C ~/laptop pull
Transferred: 36 B, 2 files
PULL raw/plot-01  2 files, 36 B <- origin
Transferred: 25 B, 1 files
PULL raw/plot-02  1 files, 25 B <- origin
$ forest -C ~/laptop pull
SKIP raw/plot-01  already synced to origin
SKIP raw/plot-02  already synced to origin

The laptop uses the same checkout name, so it reads survey/ on the remote.

Next: checkouts and remotes, stages, targeting.