Rust reimplementation of nosarthur/gita: manage many git repos with a single gita binary. Reads your existing ~/.config/gita/ layout (no migration).
gita ll- parallel repo status (one combinedgitshell script per repo on cache miss: porcelain status +show-branchsubject + relative time, matching upstream gita), fingerprint cache inll-cache.json, default 64 threads (--jobs N)- Default cold path uses
git status -uno(no untracked scan); use--full-statusfor?markers gita freeze/gita clone- export and restore repo sets (compatible with upstream freeze CSV)- Bookkeeping:
add(-r,-a),rm,rename,ls,clear,group,context,info,color,flags,workspace - Delegated commands from
cmds.json(fetch, pull,st, …) with tokio async when multiple repos gita super/gita shellpassthrough- Config:
$GITA_PROJECT_HOME/gita,$XDG_CONFIG_HOME/gita, or~/.config/gita
cargo install --path . --lockedEnsure ~/.cargo/bin is before ~/.local/bin on PATH if you previously used the Python gita from uv tool install.
cargo uninstall gita
uv tool install gitaYour ~/.config/gita/ directory is unchanged either way.
gita ll # warm: uses ~/.config/gita/ll-cache.json when repos unchanged
gita ll --refresh # cold: rescan every repo
gita ll --full-status # include untracked (?) - slower on large trees
gita ll -C # no ANSI colors
gita ll --jobs 128 # parallelism (I/O-bound; try 64-128 on many repos)
gita ll mygroup # filter by group
gita ll -g # group headers
gita freeze > repos.txt
gita clone -f repos.txt
gita clone -p -f repos.txt # preserve paths from freeze file
gita workspace add work # create an isolated workspace
gita workspace use work # switch to it (repos/groups are scoped)
gita workspace ls
gita workspace use default # switch back to the root workspace
gita -vWorkspaces are isolated gita configurations. Each workspace has its own
repos.csv, groups.csv, color.csv, info.csv, layout.csv, custom
cmds.json, ll-cache.json, and context files, all stored under
~/.config/gita/workspaces/<name>/. The root ~/.config/gita/ remains the
default workspace and is used when no workspace is active.
gita workspace add work --from-current # copy current workspace config into new workspace
gita workspace use work # all later commands use the work workspace
gita add /path/to/repo # registered in the work workspace
gita workspace show # print active workspace
gita workspace rename work job # rename a workspace
gita workspace rm job # delete a workspace (cannot be active)The active workspace is recorded in ~/.config/gita/workspace.
# bash
gita completions bash > ~/.local/share/bash-completion/completions/gita
# zsh
gita completions zsh > ~/.local/share/zsh/site-functions/_gita
# then add to .zshrc if needed: fpath=(~/.local/share/zsh/site-functions $fpath)Regenerate after upgrading gita if CLI flags change.
On 259 repos (~/.config/gita/repos.csv, macOS, release build, --jobs 64):
| Scenario | Wall time (/usr/bin/time -p gita ll >/dev/null) |
|---|---|
Cold (--refresh or no cache) |
~3.6-3.8s (259× git status; git subprocess floor on this machine) |
| Warm (unchanged repos, cache hit) | ~0.03-0.35s (fingerprint scan of 259 repos adds ~0.3s) |
Cold time is dominated by one git subprocess per repo (status + show-branch + log). Large worktrees and --full-status increase cost. The cache keys on HEAD, index mtime, stash log mtime, and FETCH_HEAD mtime (so gita fetch invalidates ahead/behind) so normal gita ll stays instant when nothing changed.
Measure locally:
rm -f ~/.config/gita/ll-cache.json
cargo build --release
/usr/bin/time -p ./target/release/gita ll --refresh >/dev/null
/usr/bin/time -p ./target/release/gita ll >/dev/nullANSI colors require a terminal that supports escape sequences (Windows Terminal, modern conhost). Use gita ll -C if colors garble output.
cargo test
cargo clippy --all-targets -- -D warnings
cargo fmt --checkMIT