# repoverse (`rv`)
Multi-repo workspace tool: keep many independent git repos in sync and roll
changes up across submodule/dependency boundaries. A Rust replacement for
hand-rolled `repo`-style bash tooling.
## Install
macOS/Linux release binary:
```sh
Windows release binary:
```powershell
With Cargo:
```sh
cargo install repoverse --bin rv
```
Update an existing install:
```sh
rv update
```
## Commands
> Proposed surface — under review. `rv` is the binary; all commands are
> `rv <cmd>`.
### Setup / onboarding
| `rv adopt [--yes] [--dry-run]` | Wizard: walk an existing nested-submodule project, propose a flat layout, dedupe repos (per-conflict fork/branch resolution), detect CI lint/test jobs → emit `.repoverse.yaml` + pinned `.repoverse.lock`. Non-destructive. |
| `rv import <manifest.xml>` | Migrate a Google-repo `manifest.xml` into `.repoverse.yaml`. |
| `rv init [--https\|--ssh]` | Clone/initialize the workspace from `.repoverse.yaml`. Scheme auto-resolves (local SSH, CI HTTPS+token). |
| `rv setup [targets...]` | Install project dependencies per repo using its package manager (resolved from CI / `.repoverse/setup` / autodetect). Auto-runs after `rv init`. |
| `rv tools` / `rv dev-setup` | Check required *system toolchains*, print install hints. |
### Inspect / sync
| `rv` / `rv status [--json]` | Tree of all repos with branch + dirty/ahead/behind. |
| `rv fetch [-j N]` | Parallel fetch all remotes; show ahead/behind. |
| `rv pull [--rebase]` | Pull each repo on its branch. |
| `rv sync [--force]` | Check the workspace out to `.repoverse.lock`. `--force` discards local changes. |
| `rv pin` | Write `.repoverse.lock` = current HEADs. |
| `rv lock-update` | Move the lock forward to current tips of the yaml's branches. |
| `rv update` | Update the installed `rv` binary. Uses Cargo when the active binary was installed with Cargo; otherwise uses the release installer. |
### Branching
| `rv branch [name]` | Smart mode: create a branch only in dirty repos. |
| `rv switch [-b] <branch> <targets...>` | Checkout/create a branch across selected repos. |
| `rv checkout <rev> <target> [--reset]` | Checkout a revision in one repo / all. |
| `rv remote <ssh\|https>` | Re-point existing clones to either scheme. |
### Workflow
| `rv commit -m "msg" [targets...]` | Atomic cross-repo commit, same message. |
| `rv push` | Push repos on feature branches. |
| `rv lint [--force] [--verbose] [targets...]` | Run lint (from CI mapping) in dirty repos, parallel, quiet on success. |
| `rv test [--force] [targets...]` | Same model, test job. |
| `rv check [targets...] [--json]` | Lint + test in parallel, aggregated pass/fail report. |
| `rv pr` | Open PRs: sub-repos first, then parent with cross-links. |
| `rv release` | Pin + commit lock + tag. |
`projects[].revision` is the branch/ref the workspace checks out and locks
from. `projects[].main_branch` is the stable PR base/trunk for that repo; it
falls back to `defaults.main_branch`, then `revision`.
### Rollup
| `rv plan [--json]` | Show the full ordered dependency DAG with per-node status (pending/dirty/branched/pr-open/ci-running/merged/blocked). |
| `rv next [--json]` | The single next actionable node: what to do, why, what's blocking it, exact commands. Stateless — agent loop primitive. |
| `rv rollup [--from <repo>] [--slug <name>] [--dry-run]` | Dependency-ordered cascade: leaves first → setup/lint/test → commit → push → PR → CI-green + auto-merge → bump consumers to merged SHA → recurse to root. |
| `rv rollup --step [<repo>]` | Execute exactly one node (the `rv next` one) and stop. Agent-in-the-loop. |
| `rv rollup --direct` | Same cascade, local fast-path: test locally → push → bump parent, no PRs. |
| `rv rollup --status [--json]` | Reconstruct rollup state from GitHub, show child checklist. |
| `rv rollup --continue` / `--abort` | Resume or abort an interrupted rollup. |
### Help
| `rv --help` / `rv help <cmd>` | Grouped command list; complete per-command help with examples. |
| `rv help topics` / `rv help <topic>` | Long-form concept pages (yaml-vs-lock, the graph, branch convention). |
## Rust workspaces — cargo path-dep identity
Symlinking duplicate submodule checkouts is necessary but not
sufficient for cargo: it identifies path deps by literal path string
and won't dedup symlinks. The pattern is to declare each shared dep
as a `git = "<url>"` source in every fork and `[patch.<url>]` it to
a single local path at the parent workspace. rv's symlinks then
ensure that path resolves to one physical checkout. Each fork's CI
mirrors the same `[patch]` against its own submodule. Full design and
the upstream `.gitmodules` constraint live in
[TODO.md → Cargo path-dep identity](./TODO.md#cargo-path-dep-identity-rust-workspaces).
## Dev
Run the debug build directly without installing:
```sh
./rv <command> # e.g. ./rv status, ./rv adopt
```
See [TODO.md](./TODO.md) for the design and roadmap.