/

Worktrees

How Veflow sets up worktrees and how to customize them with .veflow/worktree.json.

A worktree is a second checkout of a repository, with its own branch and folder. Use it to work on several features in parallel with separate files.

A fresh git worktree doesn't include untracked files such as .env or node_modules. Veflow carries over this local setup when you create a worktree.

Worktrees are a desktop app feature. Everything on this page happens locally, on your machine.

What happens when you create a worktree

When you create a worktree, Veflow carries over these local files by default:

WhatHow it's carried over
Env files — every root .env* (.env, .env.local, .env.production, …)Copied — each worktree gets its own independent copy
node_modules — root, plus packages/* and apps/* in a monorepoSymlinked to reuse the existing installation
Git hooks — Husky and custom hooksBootstrap files copied so git commit hooks still fire
Submodules — when the repo has a .gitmodulesPopulated with git submodule update --init --recursive

Setup behavior:

  • It never overwrites. If a file already exists in the new worktree, Veflow leaves it alone. Running provisioning twice is safe.
  • node_modules is shared. The symlink points to the source checkout’s installation. Package changes can affect that shared copy. Check this before installing different dependencies on a branch.
  • Setup can fail independently. The worktree remains on disk if a provisioning step fails. Check the output and complete any missing setup before starting work.

Where files come from

Veflow uses an existing checkout as the source for local files. It prefers the checkout on the default branch when available, then falls back to the primary checkout. It doesn't copy from the new worktree itself.

Customising with .veflow/worktree.json

For extra config files, shared directories, or setup commands, add .veflow/worktree.json at the repository root.

It extends the defaults (they always run first); it doesn't replace them.

{
  "copy": ["config/local.yml", "amplify/backend/amplify-meta.json"],
  "link": ["cache"],
  "submodules": true,
  "run": ["./scripts/setup-worktree.sh"]
}
FieldTypeWhat it does
copystring[]Repo-relative files or folders to copy from the source worktree. Folders are copied recursively.
linkstring[]Repo-relative folders to symlink to the source worktree's copy.
submodulesbooleanPopulate submodules. Defaults to true — set false to opt out.
runstring[]Commands to run in the new worktree after everything else. Gated by trust — see Setup commands below.

A few rules for copy and link:

  • Paths are literal — no wildcards. amplify/**/*.json won't match anything.
  • Existing destinations are skipped. Declare the specific gitignored file you need, not a whole folder that already partly exists from tracked files. (For example, amplify/.config/local-env-info.json, not amplify/.config, because that folder already exists from checked-in files.)
  • Absolute paths and .. are rejected, for safety.

This file stays out of git by default

Worktree setup can include personal paths or commands. When Veflow finds .veflow/worktree.json, it adds an ignore rule if needed to keep the file out of new commits.

An already tracked config file stays tracked. The ignore rule only affects untracked files, so teams can still share a committed configuration.

Setup commands (run)

Use run for setup that needs a command, such as rewriting a local path or running a bootstrap script. Commands execute in the new worktree after file provisioning.

Veflow asks you to approve setup commands before running them for the first time:

  1. The first time a repo's run hook would fire, Veflow shows you the repo name and the exact commands, and asks Trust & run or Skip.
  2. If you approve, Veflow remembers that decision for that repo. Future worktrees run the commands automatically — no prompt.
  3. If the commands change later, you're asked again. A trusted repo can't quietly swap in different commands behind your back.

Details:

  • Trust is per repo. In a multi-repo project, each repo is trusted independently.
  • Commands run through your login shell with the new worktree as the working directory, so your aliases, nvm, Homebrew, and PATH all resolve normally.
  • Best-effort — a failing command is logged, never blocks the worktree.
  • Your trust decisions are stored locally at ~/.veflow/worktree-trust.json.

Example: AWS Amplify

Amplify stores local state in gitignored files. One of them, local-env-info.json, contains the checkout’s absolute path. A setup command can copy the files and update that path for the new worktree:

{ "run": ["./scripts/setup-amplify-worktree.sh"] }
#!/usr/bin/env bash
set -euo pipefail

# Primary checkout (first entry of `git worktree list`) and this worktree.
MAIN=$(git worktree list --porcelain | awk '/^worktree /{print $2; exit}')
WT=$(git rev-parse --show-toplevel)
[ "$MAIN" = "$WT" ] && exit 0

# 1) Symlink the generated frontend config + env files (single source of truth).
ln -sf "$MAIN/src/aws-exports.js" "$WT/src/aws-exports.js"
for f in "$MAIN"/.env "$MAIN"/.env.*; do [ -f "$f" ] && ln -sf "$f" "$WT/$(basename "$f")"; done

# 2) Copy the Amplify local env state.
mkdir -p "$WT/amplify/.config"
cp "$MAIN/amplify/.config/"local-* "$WT/amplify/.config/" 2>/dev/null || true
cp "$MAIN/amplify/backend/amplify-meta.json" "$WT/amplify/backend/amplify-meta.json" 2>/dev/null || true

# 3) Point Amplify's projectPath at THIS worktree.
ENVFILE="$WT/amplify/.config/local-env-info.json"
[ -f "$ENVFILE" ] && sed -i '' "s#\"projectPath\": *\"[^\"]*\"#\"projectPath\": \"$WT\"#" "$ENVFILE"

The first time you make an Amplify worktree, Veflow asks you to trust this hook. After that it runs on every new worktree of that repo.

Quick reference

  • Config lives at .veflow/worktree.json in your repo root.
  • Always applied, no config: .env* copied, node_modules symlinked, git hooks, submodules.
  • copy / link skip existing destinations — declare specific gitignored paths.
  • run commands are per-repo trust-on-first-use; decisions stored at ~/.veflow/worktree-trust.json.
  • Everything is best-effort and never blocks worktree creation.

Need help?

Email hi@veflow.ai with your question or the setup error you’re seeing.