This release is a pre-release and may not be stable for production use.
RPO: Repository Participation Observer
A Python library to help you analyze and visualize Git repositories. Ever wondered who has most contributions? How participation has changed over time? What are the hotspots in your code that change frequently? Who has the highest bus factor? rpo can help.
NOTE: This is alpha software under active development. There will be breaking changes.
Install
pip install rpo
Wheels bundle a compiled Rust extension, so there is no toolchain to set
up and no git binary is shelled out to.
Usage
import rpo
ra = rpo.RepoAnalyzer("./path/to/git_repo")
ra.summary()
ra.contributor_report(identify_by="email", limit=10)
ra.file_report(limit=10)
ra.blame_report()
ra.punchcard()
Walk options are set once, on the analyzer, and apply to every report — mirroring the Rust builder:
ra = rpo.RepoAnalyzer(
path,
exclude_globs=["docs/**", "**/*.lock"],
ignore_bots=True,
first_parent_only=False,
)
Report options are keyword arguments:
ra.contributor_report(aggregate_by="committer", identify_by="email", limit=5)
Reports return polars DataFrames and print nothing, so they compose with your own analysis:
import polars as pl
(ra.file_report()
.filter(pl.col("contributors") == 1)
.sort("lines", descending=True))
The raw frames
For anything the built-in reports do not cover, take the frames
directly. commits, file_changes, blame, and blame_over_time
mirror the Rust library's terminals:
analysis = rpo.analyze(path, snapshots="monthly")
analysis.commits # one row per commit
analysis.file_changes # one row per (commit, file)
analysis.blame # per-line authorship at HEAD
analysis.blame_over_time # ...at each snapshot
Identities are canonicalized through .mailmap by the engine, so
reports group on canonical_author_name, canonical_committer_email,
and so on. File paths are path; datetimes are UTC milliseconds.
Charts
Plotting is an explicit call, never a side effect of running a report:
rpo.plotting.blame(ra.blame_report(limit=15), "img/blame.png")
rpo.plotting.cumulative_blame(ra.cumulative_blame(), "img/cblame.png")
rpo.plotting.punchcard(ra.punchcard(), "img/punchcard.png")
Any report frame also works directly with Altair through polars'
.plot accessor.
Errors
Failures from the engine surface as typed exceptions, all subclassing
rpo.RpoError: NotARepositoryError, InvalidGlobError,
RevisionNotFoundError.
Examples
Runnable scripts live in examples/, covering the frames,
every report, filtering, blame over time, charts, and custom polars
recipes. They default to analyzing this checkout:
python examples/01_quickstart.py
python examples/02_reports.py ~/src/some-other-repo
Command line
There is no python CLI. The command-line tool is
rpo-cli, installed separately:
cargo install rpo-cli
rpo summary -r ./path/to/repo
Features
- Automatically generate aliases that refer to the same person
- Support analyzing by glob
- Support excluding by glob
- Produce blame charts
- Optionally ignore merge commits
- Optionally ignore whitespace (awaiting upstream gix support)
- Identify major refactorings
- Fast execution, even on giant repositories (the engine is Rust)
Performance
The goal is for the library to work even on the largest libraries. In general, the performance is proportional to the number of authors, commits, and files being considered in the aggregations.
The authors regularly test using the cpython repository, which contains over 1,000,000 objects. That takes a while.
TODO: Performance graphs
Similar Projects and Inspiration
References
Git Commands
These are useful for validating results reported here. The git man pages for various commands is helpful reading.
All the files edited in a revision
git diff-tree --no-commit-id --name-only HEAD~1 -r
All the files present at a particular revision
git ls-tree -rlt HEAD
All commits reachable from a revision
git rev-list HEAD --count
Count all commits reachable from a revision
git rev-list HEAD --count
All commits that touch a particular object (tree in this case)
git rev-list HEAD img
All files at each commit
git rev-list HEAD | xargs -r -I % git ls-tree -rt --name-only %
git cat-file --batch-all-objects --batch-check --unordered
git rev-list --all --objects --filter=object:type=blob HEAD | git cat-file --batch-check="%(objectname) %(objecttype) %(rest) %(deltabase)"
git log --follow --pretty=format:%H -- FILE
Metadata
Release files for rpo 0.1.0b3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rpo-0.1.0b3.tar.gz | 83.5 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| rpo-0.1.0b3-cp313-abi3-win_amd64.whl | CPython 3.13 | abi3 | Windows x86-64 | Details |
| rpo-0.1.0b3-cp313-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.13 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| rpo-0.1.0b3-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.13 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| rpo-0.1.0b3-cp313-abi3-macosx_11_0_arm64.whl | CPython 3.13 | abi3 | macOS 11.0+ ARM64 | Details |
Total release size: 104.1 MB
Release files / rpo-0.1.0b3.tar.gz
| Download URL | rpo-0.1.0b3.tar.gz |
|---|---|
| Size | 83.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fab1935e80c6e31b91fdd5d8f61ed877bb36c07cd512d049abe2a6a68a04b88f
|
|
BLAKE2b-256 checksum How to use checksums |
ab66cc9840c67be251b82c37debc8d0f730a86ff27e26a1ade65c4fd6fb14f41
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.
Transparency logRelease files / rpo-0.1.0b3-cp313-abi3-win_amd64.whl
| Download URL | rpo-0.1.0b3-cp313-abi3-win_amd64.whl |
|---|---|
| Size | 24.3 MB |
| Tags | CPython 3.13 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
8f3ccbdceba859421a4bcaf533362f6d448d7095344b0f5fb63657aeb1542eb9
|
|
BLAKE2b-256 checksum How to use checksums |
3444d5e7f39b44cb862900c42cc573dc389cb64b4403a0ab752578faa954a929
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.
Transparency logRelease files / rpo-0.1.0b3-cp313-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | rpo-0.1.0b3-cp313-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 26.4 MB |
| Tags | CPython 3.13 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
80e1e04457c258ddbc08a0f1cd9aa7b1e9de356157317f4c7567a85c361fcb9d
|
|
BLAKE2b-256 checksum How to use checksums |
b86230eb5cad8e0bca9a9ebbd9670b90d957eb2fadbd1f872403eb90b898faa5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.
Transparency logRelease files / rpo-0.1.0b3-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | rpo-0.1.0b3-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 29.2 MB |
| Tags | CPython 3.13 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
9f82e2804357a9ae80d3801433d2985b8596c0d43831b91b274113a89b122bc9
|
|
BLAKE2b-256 checksum How to use checksums |
96df51a0e74eacfeac7ae380a7483b5a9355fc6ad304ec68824af67956d86820
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.
Transparency logRelease files / rpo-0.1.0b3-cp313-abi3-macosx_11_0_arm64.whl
| Download URL | rpo-0.1.0b3-cp313-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 24.1 MB |
| Tags | CPython 3.13 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
6781d3e4f06fccca08e1e245cdaedd2c1a2ab3325246c0121590a3c84d5cbf49
|
|
BLAKE2b-256 checksum How to use checksums |
86fe655ed8ed2d8b793d3097a997d358001ddc2e73acdb863c94e334a266a037
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.
Transparency log