<img src="https://raw.githubusercontent.com/antvinni/gitmole/main/docs/banner.svg" width="912" alt="gitmole"
gitmole
A toolkit for digging into any cloned git repository: who works on it, where the risk is, how old the code is, whether the repo itself is healthy, and whether anything sensitive was ever committed.
Free. Any stack. Local. Offline. Deterministic. Fast.
- Free. MIT licence, no paid tier, no account, no token. A local clone needs no credentials, and a public owner/repo is cloned with plain git. Your gh login is only used for private repositories and for owner/, and only when you ask for them. The tools it runs are open source too.
- Any stack. It reads what every repository has: the git log, git blame and the files themselves.
- Local & Offline. Everything runs against a clone on your machine. Nothing is uploaded, nothing phones home; the vulnerability database is a copy you download once. Once, on a run with a terminal, gitmole asks five yes/no questions about its own findings and writes your answers to a file it tells you how to send — it still uploads nothing, and GITMOLENOFEEDBACK=1 turns the question off for good.
- Deterministic. No AI at runtime. Every finding is a plain rule over counts you can recompute by hand. The JSON export carries each finding's rule, the numbers it fired on and, where a rule rests on a paper, the citation. The same commit gives the same bytes: gitmole's own CI runs it twice on every commit, compares the exports and attests the report. One gitmole version is one toolchain, since the five tools are pinned and installed with it, and every report records the versions it ran.
- Fast. A default run over a large repository takes a minute or two (the example reports below give their times). The expensive passes have budgets: code age is skipped when its blame pass is projected past a minute, duplicate detection when the tracked text is over 80 MB, and the report says so and how to force them (--deep).
Install
# macOS, or Linux with Homebrew: gitmole and the five tools it runs, each pinned
brew tap antvinni/gitmole https://github.com/antvinni/gitmole
brew trust antvinni/gitmole
brew install gitmole
# anywhere else: gitmole from PyPI, then the same five pinned tools into gitmole's own directory
pipx install gitmole
gitmole --install-toolsLinux package names, the release binaries, --plots and the pip caveats: docs/install.md.
Usage
gitmole . # the clone you are in
gitmole /path/to/clone # any local clone
gitmole owner/repo # clones into a temp dir first, with gh or plain git
gitmole 'owner/*' # every non-archived repo of a user or org, one summary table
gitmole . --markdown report.md # the same report as a Markdown document
gitmole . --json report.json # every table, the watch list and the findings
gitmole . --fail-on warning # exit 3 if any finding is a warning or worse
gitmole . --risk main --risk-threshold 10 # exit 3 if the files changed since main hold over 10% of the risk
gitmole . --sarif gitmole.sarif # the findings for GitHub code scanning or GitLab
gitmole . --sbom sbom.cdx.json # a CycloneDX SBOM of every package the lock files pin
gitmole . --compare last.json # what changed since an earlier --json exportgitmole . --since 2y --full # the current team, every row and column gitmole --clean # list what gitmole left behind, delete on a yes gitmole --doctor # every tool gitmole runs, the version found against the one pinned gitmole --install-tools # the five pinned tools, downloaded into gitmole's own directory
A CI job that runs `gitmole . --fail-on critical --markdown - >> "$GITHUB_STEP_SUMMARY"`
blocks on secrets in source files and still posts the report. The same
scoring wires into Claude Code, Cursor, Gemini CLI and pre-commit as a hook
that exits 2 over a threshold. Every option:
[docs/cli.md](https://github.com/antvinni/gitmole/blob/main/docs/cli.md).
## What you get
Reports on repositories you know, each at a pinned commit, published as gitmole wrote them:
| Repository | Commit | Commits | Lines | gitmole run || curl | 540ee5b5 | 39,758 | 247,179 | 59 s | | django | 8cbdd4a8 | 34,933 | 431,749 | 135 s | | react | 2b19aecd | 21,703 | 681,078 | 157 s |
Run times are one gitmole CLONE with every default step, on a MacBook Pro (M4, 16 GB).
Evolution
Every release is run from its own source over the same pinned repositories and judged by the same yardsticks, so the graphs show what each release changed (measurement.md says how). Three questions decide whether gitmole is getting better:
- Is it right? How much of the gap between a random and a perfect top
fifteen the watch list closes, against churn alone. It is drawn on the same four repositories every release (curl, django, react and gitmole), and the dots are thirteen Apache repositories nobody tuned against, scored by independent labels. Revisions × lines of code (from 0.8.0) closed most of the gap on the four. On the thirteen it closes 61% and draws with churn alone. The watch list is churn weighted by size: at the top it names about as many soon-to-be-fixed files as churn, it orders the whole pool better, and per line read it finds fewer (validation.md).