Concepts¶
How renv organizes repositories, environments, and configuration. Assumes familiarity with
git; if git worktree itself is new, see the official docs
first — renv is a layer of naming/lifecycle conventions on top of it, not a replacement.
Source vs destination¶
| Term | Meaning |
|---|---|
| Source | Directory tree of your read-only clones (--source / config source). renv create and renv add scan here for git repos. Use renv clone to populate it (layout host/owner/repo recommended). |
Destination (dest) |
Root directory where environment folders are created (--dest / config dest). |
| Environment | Named folder under dest containing one worktree subdirectory per selected repo. |
~/src/ # source (clones — never modified by renv)
github.com/ # optional host/owner/repo layout (renv clone)
my-org/
service-a/
service-b/
service-a/ # flat layout also works
service-b/
~/envs/ # dest
web/ # environment "web"
.repoenv.json # metadata + renv-root marker
service-a/ # git worktree
service-b/ # git worktree
Source clones stay untouched. All day-to-day work happens in worktrees under the environment directory.
Registry and on-disk state¶
renv keeps two layers of state:
registry.json(underREPOENV_HOME) — list of known environments, repo entries, and the active environment name..repoenv.jsoninside each environment directory — per-env metadata and an optionalmarkerblock with therenv create …command used to reproduce the env.
Lock files (.lock) next to JSON files guard concurrent writes. They include PID/host/user diagnostics and are removed after successful writes.
Environment resolution¶
When a command accepts an optional [ENV] argument, renv picks an environment in this order:
- Explicit name on the command line (
renv run web -- …) - Environment alias stored on the environment (
renv create --alias …, orrenv import --alias …) - Config alias from
repoenv.yaml/renv config aliases.<name> …(maps a short name to an environment name) - Current directory — if CWD is inside an environment path (wins over the active env; a hint is printed when they differ)
REPOENV_ACTIVE— set byrenv shfor subshell context- Active environment — set by
renv activateorrenv create --activate
If none match, the command fails with a hint to pass a name, cd into an env, or run renv activate.
Aliases (two kinds)¶
| Kind | Set via | Example | Resolves |
|---|---|---|---|
| Environment alias | renv create --alias, renv import --alias, renv merge --alias |
env ado also answers to web |
renv run web → env ado |
| Config alias | repoenv.yaml aliases: or renv config aliases.web ado |
shorthand web → env name ado |
same as typing the env name |
Both are checked when resolving an environment selector. Use config aliases for stable shortcuts in scripts; use --alias when the alias is intrinsic to one environment.
Worktrees and branches¶
Each repo worktree is a normal git worktree linked to the source clone. With --branch, renv creates a new branch from the detected default branch. Without --branch, worktrees start detached at the default branch tip.
renv add is the exception: if --branch is omitted there, and the environment already has repos
on a branch renv itself created, the new repo joins that same branch instead of landing detached
— so "I forgot a repo" doesn't require re-typing --branch. Explicit --branch always wins.
If a local branch already exists and is unused, renv attaches it automatically. If the branch is checked out elsewhere, use --on-branch-conflict detach|move|fail (default: detach for create/add/repair, move for merge — merging is explicitly about consolidating branches, and git only allows one worktree per branch, so the source environment's worktree goes detached as its branch relocates into the merged one).
Before each worktree creation, renv runs git worktree prune in the source repo to drop stale metadata.
Selecting repos¶
--include/--exclude take shell-style globs, matched against the repo's path relative to
source (so nested clones like github.com/org/repo are selected with e.g. */org/*). Multiple
values are OR-ed; comma-separated values in one flag work the same as repeating the flag.
A value starting with @ is a repo group — a saved pattern (or comma-separated patterns) set
with renv config groups.<name> <pattern> — and mixes freely with literal globs:
--include @backend,*/frontend-*. Groups and repo names both tab-complete.
Safety model¶
- Source clones: treated as read-only.
renv rm: registry-only by default;--delete-filesremoves worktrees and the env directory.renv pr: never pushes unless--pushis given; requires the GitHub CLI (gh).
See Troubleshooting for recovery when disk and registry diverge.