One workspace, many repos, one AI-maintained
CLAUDE.md.
gitm is an AI-aware multi-repo workspace orchestrator written in Rust. It groups several git projects under one workspace root, runs commands across them in parallel, syncs and opens PRs via gh/glab, and uses an AI backend (claude / opencode / codex) to auto-maintain a CLAUDE.md subproject catalog — so a multi-repo workspace becomes a ready-to-use context for AI coding agents.
- Single static binary. No Node/Python runtime, no git submodules — projects are independent clones/worktrees tracked by a TOML registry.
- Parallel by default.
gitm x -j N -- <cmd>runs a shell command across all repos in parallel. - AI-maintained docs. On
add, an AI backend reads each project's manifest and appends a| name | stack | role |row toCLAUDE.md. - Self-updating. Checks GitHub for new releases (throttled) and
gitm updatereplaces the binary in place. - AI-friendly.
gitm docsprints a token-efficient reference (llms.txt);ls --format jsonand friends give machine-readable output.
A one-line installer auto-detects your arch/OS, downloads the latest release, and installs into ~/.local/bin (no sudo needed):
curl -fsSL https://github.com/reven404/gitm/raw/main/install.sh | shOptions:
curl -fsSL https://github.com/reven404/gitm/raw/main/install.sh | sh -s -- --bin /usr/local/bin # install elsewhere (sudo yourself)
curl -fsSL https://github.com/reven404/gitm/raw/main/install.sh | sh -s -- --version v0.1.3 # pin a release
curl -fsSL https://github.com/reven404/gitm/raw/main/install.sh | sh -s -- --help # full usageThe installer warns if ~/.local/bin isn't on your PATH and prints the export PATH=... line to add to your shell rc. To install without the script (e.g. into /usr/local/bin with sudo):
ARCH=$(uname -m | sed 's/arm64/aarch64/') # aarch64 | x86_64
OS=$(uname -s | tr '[:upper:]' '[:lower:]') # darwin | linux
curl -fsSL "https://github.com/reven404/gitm/releases/latest/download/gitm-${ARCH}-${OS}.tar.gz" \
| sudo tar xz -C /usr/local/bin gitm
gitm versionPrebuilt assets (per release):
| Asset | Host |
|---|---|
gitm-aarch64-darwin.tar.gz |
Apple silicon (macOS) |
gitm-x86_64-darwin.tar.gz |
Intel (macOS) — cross-compiled on Apple-silicon runner |
gitm-aarch64-linux.tar.gz |
arm64 (Linux, e.g. Graviton/Raspberry Pi) |
gitm-x86_64-linux.tar.gz |
x86_64 (Linux) |
cargo install --git https://github.com/reven404/gitm --lockedgit clone https://github.com/reven404/gitm
cd gitm
cargo build --release
# binary: target/release/gitmOnce installed, gitm self-updates from the same GitHub releases:
gitm update --check # show current vs latest
gitm update # download + extract + replace the running binarygitm init myws # create workspace, detect AI backend, scan sub-repos
cd myws
gitm add git@github.com:org/service.git --tag backend # clone (branch = "myws")
gitm add ../local-repo --tag frontend # worktree of a local repo
gitm ls # live status: branch / dirty / ahead / behind
gitm ls --format json
gitm x -j 4 -- 'make test' # run across all projects in parallel
gitm x -t backend -- 'go build ./...' # filter by tag
gitm x --dry-run -- 'make test' # preview
gitm sync # fetch + ff-only pull, skip dirty
gitm rm service # unregister (+ worktree remove)The root CLAUDE.md gets a Subproject Catalog row per project, filled by the AI backend:
| service | Node 18 + Egg.js | 表单后端服务 |
| Command | Description |
|---|---|
gitm init [DIR] [--ai <b>] [--no-scan] |
Init workspace, write CLAUDE.md, detect AI backend, scan existing git sub-repos. The workspace root is a plain directory, not a git repo — subprojects are independent clones/worktrees. |
gitm add <SRC> [NAME] [--tag <T>]... |
git clone (URL) or git worktree add (local path); branch = workspace name; writes toml + AI row. |
gitm ls [--format table|json] [--tag <T>] |
Live status per project. |
gitm x [-p NAME] [-t <T>] [-j N] [--fail-fast] [--dry-run] -- <CMD> |
Run a shell command across projects in parallel. -- separates. |
gitm sync [-j N] |
git fetch --prune + git pull --ff-only; skips dirty repos. |
gitm rm <NAME> [--force] |
Unregister; worktree-removes worktrees, deletes cloned with --force, keeps local. |
gitm ai [NAME] [--refresh] |
Re-run AI analysis, rewrite CLAUDE.md rows. |
gitm version |
Print version / target / repo / detected AI backends. |
gitm update [--check] |
Check GitHub for a newer release; download + self-replace. |
gitm docs |
Print the AI-friendly reference (same as llms.txt). |
Global flags (placed before the subcommand): --no-ai, --ai <backend>, --no-check, -v.
Simple commands need no quotes — gitm execs the program directly:
gitm x -j 4 -- go build ./...
gitm x -t backend -- npm run test
gitm x -- git status -sbIf any argument contains shell control chars (&&, |, ;, $, globs, >, ...), gitm runs it through sh -c instead — so quote the whole script to keep it as one argument:
gitm x -- 'make test && make build'
gitm x -- 'echo $(basename "$PWD")'The -- separator is required so gitm doesn't confuse your command's flags with its own.
[workspace]
branch = "myws" # default branch for all sub-projects (= init dir basename)
[ai]
backend = "claude" # claude | opencode | codex | none
[[project]]
name = "service"
source = "git@github.com:org/service.git"
type = "cloned" # cloned | worktree | local
path = "service"
branch = "myws" # optional override of [workspace].branch
tags = ["backend"]find_root() walks up from cwd to locate gitm.toml, so commands work from any subdirectory of the workspace.
At init, gitm probes PATH for claude, opencode, codex (via --version). If multiple are found it prompts you to pick one; --ai <backend> skips the prompt. Non-interactive (no TTY) falls back to the first detected. Override anytime with --ai or by editing [ai].backend.
Each backend is invoked non-interactively with the project dir as cwd so it can read manifest files:
| Backend | Invocation |
|---|---|
| claude | claude -p "<prompt>" |
| opencode | opencode run "<prompt>" |
| codex | codex exec "<prompt>" |
AI is best-effort: on failure or --no-ai, a | <name> | (pending) | | placeholder row is written and can be filled later with gitm ai --refresh <name>.
gitm checks GitHub for a newer release on startup, throttled to once per 24h (cached at ~/.cache/gitm/last_check). If a newer version exists it prints a one-line notice; the check is silent on network failure and never blocks.
gitm update --check # show current vs latest
gitm update # download matching asset, extract, replace the running binaryRepo is reven404/gitm by default; override at build time with GITM_REPO_OWNER / GITM_REPO_NAME env vars. Release assets are named gitm-<arch>-<os>.tar.gz and produced by .github/workflows/release.yml on v* tag push. --no-check skips the startup check (CI / offline).
| Marker | Meaning |
|---|---|
✔ |
clean, in sync with upstream |
✱dirty |
uncommitted changes |
↑N |
N commits ahead of upstream |
↓N |
N commits behind upstream |
∅no-upstream |
no tracking branch |
| gitm | meta | mani | multi-gitter | |
|---|---|---|---|---|
| Language | Rust | Node.js | Rust | Go |
| Registry | TOML | .meta JSON |
TOML/YAML | — |
| Parallel exec | ✅ | ❌ (passthrough) | ✅ | ✅ |
| Tags/groups | ✅ | ❌ | ✅ | — |
Auto CLAUDE.md via AI |
✅ | ❌ | ❌ | ❌ |
| Self-update | ✅ | ❌ | ❌ | — |
| Fleet PR lifecycle | ❌ | ❌ | ❌ | ✅ |
gitm's differentiation is the AI-maintained CLAUDE.md; for fleet-level mass PRs across an org use multi-gitter.
- Fleet-level PR lifecycle (merge/close/status across an org) — multi-gitter.
- Manifest version pinning (commit SHAs) — Google's
repo. - Recursive/nested workspaces, Windows support (
sh -c), self-hosted Git API beyondgh/glab.
MIT