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 for your platform:
curl -fsSL https://github.com/releasetools/multirepo/raw/main/install.sh | sh Or build from a checkout with ./install.sh --local. Then source the shim:
# zsh — add to ~/.zshrc
source /path/to/multirepo/multirepo.plugin.zsh
# bash — add to ~/.bashrc
source /path/to/multirepo/multirepo.plugin.bash
# fish — add to ~/.config/fish/config.fish
source /path/to/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": [
{ "name": "api", "path": "api" },
{ "name": "web", "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 new 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 config # 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.
What it does
Everything lives in the .code-workspace file, so there's no
separate config to keep in sync.
-
A workspace is just its
.code-workspacefile; a machine-local registry only remembers where each one lives. -
Enabled state drives
.claudeignore,.geminiignore, and the editor's file exclusions, so AI tools see only the repos you choose. -
cdinto a workspace and it activates;@<repo>jumps into any repo by name. - Every command is idempotent. Reconcile fast-forwards or rebases only where the tree is clean, and never touches dirty or unpushed work.
-
A shared
.code-workspaceis read as untrusted input, so a stray entry can't inject a git option or escape the workspace directory. - Clones, fetches, and status run in parallel with a live progress row each, and a cooperative lock keeps two runs from colliding on the same repo.
-
Repos clone from a
gitURL, GitHub viagh, or GitLab.
The commands:
| Command | What it does |
|---|---|
new [dir] | Scaffold a .code-workspace from the git repos already in a directory, inferring each one's source from its origin remote. |
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. |
status | Show git state across every repo. -o table for a columnar view, -a for every workspace. Reads local state, so it's fast and offline. |
config | Pick which repos are enabled. Enabled state drives .claudeignore, .geminiignore, and the editor's file exclusions. |
@<repo> | Change into a repo's directory by name. |
ls / select | List every workspace on the machine, or switch to another with a filterable picker. |
prune / reset | Drop branches whose upstream is gone; bring clean repos back to their main branch. |
lock | Show the cooperative per-repo locks across the workspace: what's free, what's held, and whether each hold is alive or stale. |
rm | Unregister a workspace from the registry (files on disk stay put). |
New here? The guide walks through the common tasks. See the changelog for what's new, or the repository for the full spec.