multirepo

multirepo

Manage many git repositories from one .code-workspace file — clone them, keep them in sync, and jump between them by name.

One small Rust binary does the work. A thin shell shim (zsh, bash, fish) wires it into your shell, so cd-ing into a workspace just works.

Install

Download a prebuilt binary and the shell shims:

curl -fsSL https://github.com/releasetools/multirepo/raw/main/install.sh | sh

Or build from a checkout with ./install.sh --local. The installer offers to wire the shim into your shell rc; if you decline, add the line yourself:

# zsh — add to ~/.zshrc
[ -f "$HOME/.local/share/multirepo/multirepo.plugin.zsh" ] && . "$HOME/.local/share/multirepo/multirepo.plugin.zsh"

# bash — add to ~/.bashrc
[ -f "$HOME/.local/share/multirepo/multirepo.plugin.bash" ] && . "$HOME/.local/share/multirepo/multirepo.plugin.bash"

# fish — add to ~/.config/fish/config.fish
test -f "$HOME/.local/share/multirepo/conf.d/multirepo.fish"; and source "$HOME/.local/share/multirepo/conf.d/multirepo.fish"

Quickstart

A workspace is any directory with a *.code-workspace file. Add a multirepo block that lists your repos — each one says where it comes from (git, github, or gitlab), where it lives on disk, and whether it's enabled:

{
  "folders": [
    { "path": "api" },
    { "path": "web" }
  ],
  "multirepo": {
    "version": 1,
    "repositories": {
      "api": { "source": "github", "repo": "your-org/api", "path": "api", "enabled": true },
      "web": { "source": "git",    "url": "git@github.com:your-org/web.git", "path": "web", "enabled": true }
    }
  }
}

Already have the repos checked out? multirepo workspace create writes that file for you — it scans a directory, reads each repo's origin remote, and lists them with the right source.

Then let multirepo set it up and move you in:

# in the directory holding your-project.code-workspace
multirepo sync          # clone the repos and drop you in
@api                    # jump into the api repo by name
multirepo status        # git state across every repo
multirepo focus         # pick which repos AI tools and the editor see

Run multirepo sync ./other.code-workspace with a file to set up a fresh copy somewhere new; run multirepo sync with no file to reconcile the workspace you're already in. multirepo sync --all reconciles every registered workspace's repos in place — no activation or cd, you stay where you are.

Cloned a repo into the workspace by hand? multirepo focus spots it and offers to adopt it, or run multirepo focus --add <dir> to add it straight away — the source is read from its origin. Done with a repo? multirepo focus --rm <dir> drops it from the workspace and leaves the clone on disk.

What it does

Everything lives in the .code-workspace file, so there's no separate config to keep in sync.

The commands:

CommandWhat it does
workspace create [dir]Scaffold a .code-workspace from the git repos already in a directory, inferring each one's source from its origin remote. Alias ws.
sync [file]Set up a workspace, or reconcile the current one: clone missing repos, fast-forward what's behind, rebase what diverged, leave dirty repos alone. --all reconciles every registered workspace in place.
statusShow git state across every repo. -o table for a columnar view, -a for every workspace. Reads local state, so it's fast and offline.
focusPick which repos are enabled, and adopt (--add <dir>, or the picker) or drop (--rm <dir>) repos. Enabled state drives .claudeignore, .geminiignore, and the workspace's folders list (a disabled repo is hidden from the editor and AI tools).
@<repo>Change into a repo's directory by name.
feature create <name> [repos…]Spin up a feature: a named subset of repos, each checked out as a git worktree on a shared feature/<name> branch under .multirepo/feature/<name>/, with its own .code-workspace to open. Inside it, status/sync/focus/… act on the feature's worktrees. Alias feat.
feature rm <name>Tear a feature down: removes its worktrees after flagging any dirty, unpushed, or unmerged work (refuses without --force), and keeps the branches.
select [name]Switch workspace. With a name, jump straight there. With no args, one screen over every workspace: ←/→ switch workspace, ↑/↓ + space toggle its repos; enter saves every workspace you changed and moves you into the highlighted one. (To enter a feature, cd into its dir.)
workspace lsList every workspace on the machine. -a nests each one's repos and features; --prune drops entries whose files are gone. Alias ws.
prune / resetDrop branches whose upstream is gone; bring clean repos back to their main branch.
lockShow the cooperative per-repo locks across the workspace: what's free, what's held, and whether each hold is alive or stale.
workspace rm [names…]Unregister a workspace from the registry (files on disk stay put). Alias ws.

New here? The guide walks through the common tasks. See the changelog for what's new, or the repository for the full spec.