repoverse 0.1.7

Multi-repo workspace tool: keep many git repos in sync and roll changes up across dependency boundaries
# 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
curl -fsSL https://raw.githubusercontent.com/madhavajay/repoverse/main/install.sh | sh
```

Windows release binary:

```powershell
irm https://raw.githubusercontent.com/madhavajay/repoverse/main/install.ps1 | iex
```

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

| Command | What it does |
|---|---|
| `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

| Command | What it does |
|---|---|
| `rv` / `rv status [--json]` | Tree of all repos with branch + dirty/ahead/behind. |
| `rv status --dirty` | File-level working-tree status across the root and all configured repos. |
| `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 branch-sync [--pull]` | Check repos out to `.repoverse.yaml` branches (`revision`, falling back to `main_branch`/defaults); `--pull` pulls them. |
| `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

| Command | What it does |
|---|---|
| `rv branch <name> [targets...]` | Smart mode: create/switch a branch in dirty repos and update `.repoverse.yaml` `revision` plus matching `links[].branch`. Use `--all` for every targeted repo or `--no-write-config` for local-only branches. |
| `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

| Command | What it does |
|---|---|
| `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

| Command | What it does |
|---|---|
| `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

| Command | What it does |
|---|---|
| `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.