Run git across all child repositories — fast.
Current release: 1.3.0 · Docs: https://gg.chtnnhfoundation.org/
gg discovers git repos under a directory and runs git commands (or built-in insights) in parallel. One CLI for multi-checkout workspaces, client folders, and polyrepos.
# overview of every child repo
gg
# passthrough: git status in each repo
gg status -sb
# only dirty repos
gg --only-dirty pull
# target an alias or group
gg -g work fetch --all
# show paths next to repo names (also: show_path = true in config)
gg --show-path ov
# top commits across selection
gg commits -n 10brew tap chtnnh/tap # first time; may need: brew trust chtnnh/tap
brew install git-gist
# or: brew install chtnnh/tap/git-gist
brew update && brew upgrade git-gist # later releasesIf gg version still looks old after upgrading, Homebrew’s gg may be shadowed by ~/.cargo/bin/gg. Check with which -a gg, or use /opt/homebrew/opt/git-gist/bin/gg (Apple Silicon) / /usr/local/opt/git-gist/bin/gg (Intel).
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/chtnnh/git-gist/releases/latest/download/git-gist-installer.sh | shWindows (PowerShell):
irm https://github.com/chtnnh/git-gist/releases/latest/download/git-gist-installer.ps1 | iexcargo install git-gist --locked
# or from this repo:
cargo install --path . --locked
# binary: ggDownload .deb / .rpm from GitHub Releases, or build with cargo deb / cargo generate-rpm (see packaging/README.md).
nix run github:chtnnh/git-gist -- version
nix profile install github:chtnnh/git-gistOperator guide for brew/deb/rpm/nix: packaging/README.md.
# bash
command 'gg' doctor --shell bash
eval "$(command 'gg' doctor --shell bash --setup)"
source <(curl -fsSL https://raw.githubusercontent.com/chtnnh/git-gist/main/shell/gg.bash) # or local path
# zsh
command 'gg' doctor --shell zsh
eval "$(command 'gg' doctor --shell zsh --setup)"
source /path/to/git-gist/shell/gg.zsh
# fish
command 'gg' doctor --shell fish
command 'gg' doctor --shell fish --setup | source
source /path/to/git-gist/shell/gg.fishdoctor --shell scans the standard persisted startup files. command 'gg' bypasses an existing shell alias/function, including Zsh global aliases, long enough for the setup snippet to check the active shell too. The snippets and helpers are idempotent and refuse to overwrite or use a collision; remove or rename the existing gg definition first. Helpers provide gg-cd <alias> and an optional prompt snippet.
Interactive config (wizard / TUI): see the Interactive config chapter.
| Command | Description |
|---|---|
overview / ov |
Dashboard: branch, dirty, ahead/behind (colored) |
list / ls |
List discovered repos |
info |
Detailed status |
commits -n |
Top-N commits |
worktrees |
Worktree listing |
doctor / doctor --config / `doctor --shell <bash |
zsh |
each |
Run arbitrary shell in each repo (sh / Windows cmd) |
sync [--pull] |
Fetch (+ optional ff-only pull) |
update |
Force enroll from [[auto_enroll]] (also runs automatically) |
stale --days N |
Repos without recent commits |
alias / group / tag |
Manage aliases, groups, tags (wizard / ui / prune) |
config |
Show/get/set/edit; wizard / ui / enroll |
wizard / ui |
Interactive config hub (prompts / full-screen TUI) |
init / scaffold |
Scaffold from a profile |
hooks |
Install hook packs |
remotes |
Remote catalog (wizard / ui) |
completions |
Shell completions |
man |
Generate man pages (root + nested subcommands) |
self-update |
Update guidance / release probe |
Anything else is passed through to git in each selected repo. Escape hatch: gg git -- <args>.
- Global:
~/.git-gist/config.toml(legacy XDG / Application Support paths migrate automatically) - Local:
.gg.tomlor.git-gist.toml(walks up from cwd) - Ignore globs: config
ignore+.ggignore - Interactive:
gg config wizard/gg config ui(alsogg alias wizard,gg group ui, …)
schema_version = 1
depth = 6
jobs = 8
theme = "vivid"
show_path = false # or true / use --show-path
ignore = ["**/node_modules/**", "**/target/**"]
[aliases]
api = "/Users/you/src/api"
web = "/Users/you/src/web"
[groups]
work = ["api", "web"]
[remotes]
origin-template = "git@github.com:org/{name}.git"
[profiles.default]
default_branch = "main"
user_name = "You"
user_email = "you@example.com"
[[auto_enroll]]
path = "/Users/you/src"
path_prefix = "learning/"
depth = 6
tags = ["learning"]Remote catalog values may be complete URLs, {name} / {repo} templates, or
user@host:path SSH prefixes ending in / or :. gg remotes add-to and
gg init expand templates and SSH prefixes using the repository directory name;
complete URLs and local paths stay literal.
--root,--in/-i,--exclude/-x,-g <group>,--tag,--depth-jjobs,--fail-fast,--dry-run,--timing,-q/--quiet--only-dirty,--only-clean,--only-ahead,--only-behind, …--format human|json|ndjson,--color auto|always|never,--theme,--show-path
Selection notes:
--rootdoes not pull in aliases outside that tree (use-i).--depthalso applies to under-root aliases.- An existing directory for
-i/-xincludes or excludes all selected repos under that prefix. - Selection flags apply to reporting and multi-repo commands (
ov,list,sync,each, passthrough, …). Catalog/config commands (alias,group,config,hooks list, …) ignore them. - Put global flags before external git verbs (
gg --dry-run status). Misplaced globals after the verb error with a hint.
- Config lives in
~/.git-gist/; interactivewizard/uifor aliases, groups, tags, remotes, auto-enroll - Automatic (throttled) auto-enroll;
gg update --prune-stale/gg alias prunereclaim short names after moves path_prefixon[[auto_enroll]], selection summaries for-g/--tag,gg doctor --config
Full notes: CHANGELOG.md. Planned follow-ups stay under [Unreleased].
- Online: https://gg.chtnnhfoundation.org/
- Source:
website/(Docusaurus). Local:cd website && npm install && npm start - Before commit/push:
./scripts/ci.sh
MIT — see LICENSE.

