multirepo

Changelog

2026-06-01

This release adds a way to start a workspace from repos you already have, a hands-on guide, and a clearer picture of the tool for AI assistants.

Start a workspace from repos you already have: new

new builds a .code-workspace from the git repositories already sitting in a directory. Point it at a directory (or none, for the current one) and it writes a workspace file listing every repo it finds. It works out each repo’s source from that repo’s own origin remote: a github.com remote becomes a github source when gh is set up, a gitlab.com remote a gitlab source, and anything else a plain git source with its exact URL. By default it opens a picker with everything checked, so you can drop a repo or two before writing; pass --all, or run it without a terminal, to take all of them. Non-git subdirectories, and git repos with no origin, are skipped with a note. It only writes the file, and won’t overwrite a different one already there.

A hands-on guide

A guide walks through the common tasks in order: starting a workspace from repos you already have, setting one up from a file, moving between repos, and choosing what AI tools see. It’s a single file in the repo rendered as a page on the site.

A clearer picture for AI assistants

A context7.json and an llms.txt at the repo root give AI coding tools an accurate description of multirepo — what each command does and when to reach for new or sync. Assistants that read them, through Context7 or an llms.txt, can drive the tool correctly.

2026-05-31

This release adds working across several workspaces, output options for status, cooperative locking, and safety around shared workspace files.

Work across several workspaces

multirepo keeps a registry of every workspace you’ve set up on this machine. ls lists them, with the current one marked. select opens a filterable picker: type to narrow the list, enter to jump. rm drops a workspace from the registry without touching anything on disk — pass names, or run it with no arguments to pick from a list and confirm. Point MULTIREPO_CONFIG at a file to keep the registry somewhere else, handy for scratch setups that shouldn’t touch your real list.

Two layouts for status

status prints one repo per line with a plain-English summary by default (clean, 3 modified, 2 ahead, 1 to prune). -o table switches to a wider columnar view with separate dirty, ahead, behind, and gone columns. -a/--all runs across every registered workspace. Each run starts with a header naming the workspace. status reads local git state only, so it’s fast and works offline; fetching is sync’s job.

Cooperative locking and the lock command

When sync, prune, or reset work on a repo, they first take a cooperative lock at <repo>/.git/multirepo.lock, so two multirepo runs over the same repo don’t step on each other — the second skips the busy repo and says so. Locks are scoped per worktree, so separate checkouts don’t block one another. lock shows what’s held across the workspace: which repos are free, which are locked, and for each lock whether it’s alive or stale, plus its pid, age, and the operation holding it.

Safety around shared workspace files

A .code-workspace file is meant to be shared, so multirepo reads it as untrusted input. A hostile remote URL can’t slip in as a git option, and a repo entry can’t point outside the workspace directory with .. or an absolute path. Unsafe entries are ignored, with a warning that names the problem.

Disabling a repo hides it everywhere

Toggling a repo in config updates the workspace’s folder list and the ignore files together, so the editor and AI tools agree on what’s hidden.

Context follows the directory

A workspace counts as active only while you’re inside its directory. cd out of the tree and commands stop acting on it; the environment still remembers it, so stepping back in is instant. Removing the workspace you’re in clears its @ aliases and environment on your next command, and a removed workspace stays removed — acting on one that isn’t registered prints a clear message pointing you at sync.

Install through your plugin manager

The shim files sit where Fisher, Oh My Zsh, zinit, and bash-it look, so a plugin manager can install them, or you can source the path by hand. bash has its own entry point that loads the shared shim.

2026-05-30

First release. multirepo manages a set of git repositories as one workspace, described by a single .code-workspace file, with a thin shell layer for navigation.

One binary, one shell shim

multirepo is a single Rust binary. A small shim for zsh, bash, and fish wires it into your shell and runs the shell code the binary prints — the way a tool can change your current directory and aliases from the outside.

Workspaces live in the .code-workspace file

A workspace is any directory with a *.code-workspace file that carries a multirepo block listing its repos. Each repo records where it comes from (git, github, or gitlab), where it lives on disk, and whether it’s enabled. That one file is the source of truth, so there’s no separate config to keep in step.

Set up and stay current with sync

sync sets a workspace up and keeps it current. Given a workspace file it clones every repo and drops you in. With no file it reconciles the workspace you’re in: cloning anything missing, fast-forwarding what’s behind, rebasing what has diverged, and leaving dirty or unpushed repos untouched.

Jump between repos with @ aliases

Activating a workspace defines an @<repo> alias for each repo, so you can hop into any of them by name. cd-ing into a workspace activates it, and leaving it puts your shell back.

Choose what AI tools see with config

config opens a picker to choose which repos are enabled. Enabled state drives .claudeignore, .geminiignore, and the workspace’s files.exclude, so AI tools and the editor see only the repos you pick.

The rest of the commands

status shows git state across every repo at a glance. prune clears local branches whose upstream is gone. reset brings clean repos back to their main branch. ls lists every workspace on the machine, and select switches between them.

Built for many repos at once

Clones, fetches, and status run in parallel, with a live progress row per repo; concurrency is capped automatically and tunable with --jobs. Repo names carry a stable color so the same repo always reads the same way, and color steps aside for NO_COLOR and non-terminal output.

Install and updates

A one-line installer downloads a prebuilt binary for your platform, or builds from source with --local. Tagged releases ship checksum-verified tarballs for macOS and Linux through GitHub Releases.