Command line

Reesync brings an existing project up to date with a newer version of the starter it was generated from. When a new starter archive is published, unpack it somewhere, then run reesync from inside your project pointing at the unpacked folder:

reesync <TEMPLATE_DIR>

<TEMPLATE_DIR> is any directory to compare against - an unpacked starter archive is the common case, but a sibling checkout of the upstream repository works the same way. Reesync only reads from it; your project is the only thing ever written to.

Interactive workflow

  1. Diff - Reesync walks both directories and identifies files that differ: new files (added by the newer starter), modified files (content differs), and deleted files (exist only in your project).
  2. Browse the tree - navigate the file tree with arrow keys. Folders are collapsible. New and modified files are pre-checked; deleted files are marked [─] (deleted), dimmed, and cannot be copied. Files matched by .reesyncignore are dimmed and pre-unchecked.
  3. Toggle files - press Space to check or uncheck individual files. Toggling a folder checks or unchecks all its children at once. A folder shows [~] when only some of its children are selected, [x] when all are.
  4. Confirm - press Enter to copy the selected files from the starter into your project. Progress is shown per file.
  5. Done - Reesync prints a summary and exits. Only the files you checked are written; nothing else in your project is touched.

Key bindings

KeyAction
/ Navigate tree items
Expand a collapsed folder
Collapse an expanded folder
SpaceToggle the current item's checkbox
iAdd or remove the current file in .reesyncignore
EnterConfirm selection and begin sync
q / EscQuit without syncing

Options

FlagDescription
--version, -v, -VPrint the version and exit.
--wherePrint the directory the binary lives in and exit.

Example

# A new starter archive was published - unpack it, then pull in what you want
unzip ~/Downloads/reepolee-starter.zip -d /tmp/reepolee-new

cd ~/code/demo-ree
reesync /tmp/reepolee-new

Reesync compares the two directories, presents only the files that differ, and copies whichever ones you confirm. Files that are identical between the two directories are never shown.

What gets compared

Reesync walks both directories, but skips two categories outright - they never appear in the tree and are never synced:

  • Hidden files and directories - anything whose name starts with a dot. This is why .reesyncignore can never sync over itself, but it also means dotfiles like .gitignore are not brought over from a newer starter. Update those by hand.
  • Build and dependency directories - .git, node_modules, target, vendor, vendors, dist, .next, .svelte-kit, .cache, and .output.

Everything else is compared by content hash, so a file that merely moved timestamps is not reported as changed. If nothing differs, Reesync prints No differences found and exits without opening the tree.

Ignoring files

Some files in your project are yours alone and should never be pulled in from a newer starter. List them in a .reesyncignore file at the root of your project:

# One glob pattern per line; blank lines and # comments are ignored
src/config/branding.ts
src/public/img/**
*.local.json

Each non-blank, non-comment line is a globset pattern, matched against the path of each differing file relative to your project root. Matching files are shown but pre-unchecked, dimmed and marked (ignored) - never hidden. This is deliberate: you still see that the starter changed the file, you just don't copy it by accident.

The file is owned by your project rather than the starter, and Reesync skips it during the diff, so it never syncs over itself. A missing .reesyncignore is not an error, and an invalid pattern is skipped with a warning rather than breaking the run.

Press i in the tree to add or remove the highlighted file. On a folder, i toggles every file beneath it as a group. Because i manages exact-path lines only, a file matched by a broader glob (src/public/img/**) can't be toggled this way - Reesync tells you which pattern matched so you can edit the file by hand.

Commit context

If the directory you point at happens to be a git repository, Reesync appends the subject of the last commit that touched each file to its row in the tree, so you can see why a file changed before deciding to take it. An unpacked archive has no git history, so the suffix is simply omitted - everything else works the same.