Pretty Git
English | Русский
Generator of rich reports for a local Git repository: summary, activity, authors, files, heatmap, languages, hotspots, churn, ownership. Output to Console and formats: JSON, CSV, Markdown, YAML, XML.
— License: MIT.
Table of Contents
- Features
- Requirements
- Installation
- Quick Start
- CLI and Options
- Filters
- Output format
- Write to file
- Exit codes
- Reports and Examples
- summary — repository summary
- activity — activity (day/week/month)
- authors — by authors
- files — by files
- heatmap — commit heatmap
- languages — languages
- hotspots — hotspots (risky files)
- churn — code churn by file
- ownership — code ownership
- Exports
- Console
- JSON
- CSV
- Markdown
- YAML
- XML
- Determinism and Sorting
- Windows Notes
- Diagnostics and Errors
- FAQ
- Development
- License
✨ Features
-
Reports:
summary,activity,authors,files,heatmap,languages,hotspots,churn,ownership. - Filters: branches, authors, paths, time period.
-
Exports:
console,json,csv,md,yaml,xml. -
Output: to stdout or file via
--out.
❓ Why Pretty Git
- One tool, many views: activity, authorship, hotspots, languages, ownership — consistent UX and outputs.
- Deterministic results: stable sorting and formatting make it reliable for CI and diffs.
- Format-first: JSON/CSV/Markdown/YAML/XML out of the box with strict and documented rules.
-
Fast enough for daily use: streams
git logand aggregates in-memory; tips below for large repos. -
Safe defaults: sensible path and binary ignores for the
languagesreport; colorized console output with themes.
⚙️ Requirements
- Ruby: >= 3.4 (recommended 3.4.x)
-
Git: installed and available in
PATH
📦 Installation
🍺 Homebrew (recommended)
brew tap MikoMikocchi/tap
brew install pretty-git♦️ RubyGems
gem install pretty-gitChoose one:
- 🛠️ From source (recommended for development)
git clone <repo_url>
cd pretty-git
bin/setup
# run:
bundle exec bin/pretty-git --help- ♦️ As a gem (after the first release)
gem install pretty-git
pretty-git --version- 📦 Via Bundler
# Gemfile
gem 'pretty-git', '~> 0.1'bundle install
bundle exec pretty-git --help🚀 Quick Start
# Repository summary to console
bundle exec bin/pretty-git summary .
# Authors in JSON written to file
bundle exec bin/pretty-git authors . --format json --out authors.json
# Weekly activity for period only for selected paths
bundle exec bin/pretty-git activity . --time-bucket week --since 2025-01-01 \
--paths app,lib --format csv --out activity.csv🧰 CLI and Options
General form:
pretty-git <report> <repo_path> [options]Notes:
-
<repo_path>defaults to.if omitted. - You can also pass the repository via
--repo PATHas an alternative to the positional argument.
Available reports: summary, activity, authors, files, heatmap, languages, hotspots, churn, ownership.
Key options:
-
--format, -f
console|json|csv|md|yaml|xml(defaultconsole) - --out, -o Path to write output file
-
--limit, -l Number of items shown;
allor0— no limit -
--time-bucket
day|week|month(foractivity) -
--since/--until Date/time in ISO8601 or
YYYY-MM-DD - --branch Multi-option, can be specified multiple times
- --author/--exclude-author Filter by authors
- --path/--exclude-path Filter by paths (comma-separated or repeated option)
- --no-color Disable colors in console
-
--theme
basic|bright|mono— console theme (defaultbasic;monoforces monochrome) -
--metric
bytes|files|loc— metric forlanguagesreport (defaultbytes) - --verbose Print debug information (effective git command, filters)
Examples with multiple values:
# Multiple branches (treated as explicit revisions)
pretty-git summary . --branch main --branch develop
## This is equivalent to:
## git log main develop -- ...
# Filter authors (include/exclude)
pretty-git authors . --author alice@example.com --exclude-author bot@company
# Filter paths
pretty-git files . --path app,lib --exclude-path vendor,node_modulesFilters
Filters apply at commit fetch and later aggregation. Below — exact semantics and tips.
Branches / revisions
-
--branch BRANCHmay be provided multiple times. - Multiple branches are treated as explicit revisions to
git log(no implicit merge-base range). Example:--branch main --branch develop→git log main develop -- .... - If no branches are specified, the repository’s current
HEADis used.
Authors
-
--authorand--exclude-authoraccept name or email substrings (case-insensitive match bygit log). - Multiple values may be provided by repeating the option.
Paths
-
--pathand--exclude-pathaccept comma-separated values or repeated options. - Globs are supported by git pathspec. Excludes are translated to
:(exclude)patternand applied consistently. - When only excludes are present,
.is included to ensure the pathspec is valid (mirrors tests inspec/pretty_git/git/provider_spec.rb).
Time period
-
--since/--until: ISO8601 (e.g.2025-01-31T12:00:00Z) orYYYY-MM-DD. - Date-only values are interpreted as UTC midnight to avoid timezone drift in different environments.
- Time values are normalized to UTC in outputs.
Verbose diagnostics
-
--verboseprints the effectivegit logcommand and active filters to stderr. - Useful for debugging filters, CI logs, or when reproducing results locally.
Output format
Set via --format. For file formats it’s recommended to use --out.
Write to file
pretty-git authors . --format csv --out authors.csvExit codes
-
0— success -
1— user error (unknown report/format, bad arguments) -
2— system error (git error etc.)
📊 Reports and Examples
🧭 summary — repository summary
pretty-git summary . --format jsonContains totals (commits, authors, additions, deletions) and top authors/files.
📆 activity — activity (day/week/month)
pretty-git activity . --time-bucket week --format csvCSV columns: bucket,timestamp,commits,additions,deletions.
JSON example:
[
{"bucket":"week","timestamp":"2025-06-02T00:00:00Z","commits":120,"additions":3456,"deletions":2100},
{"bucket":"week","timestamp":"2025-06-09T00:00:00Z","commits":98,"additions":2890,"deletions":1760}
]👤 authors — by authors
pretty-git authors . --format md --limit 10CSV columns: author,author_email,commits,additions,deletions,avg_commit_size.
Markdown example:
| author | author_email | commits | additions | deletions | avg_commit_size |
|---|---|---:|---:|---:|---:|
| Alice | a@example.com | 2 | 5 | 1 | 3.0 |
| Bob | b@example.com | 1 | 2 | 0 | 2.0 |📁 files — by files
pretty-git files . --paths app,lib --format csvCSV columns: path,commits,additions,deletions,changes.
XML example:
<?xml version="1.0" encoding="UTF-8"?>
<report>
<report>files</report>
<generated_at>2025-01-31T00:00:00Z</generated_at>
<repo_path>/abs/path/to/repo</repo_path>
<items>
<item>
<path>app/models/user.rb</path>
<commits>42</commits>
<additions>2100</additions>
<deletions>1400</deletions>
<changes>3500</changes>
</item>
<item>
<path>app/services/auth.rb</path>
<commits>35</commits>
<additions>1500</additions>
<deletions>900</deletions>
<changes>2400</changes>
</item>
</items>
</report>🔥 heatmap — commit heatmap
pretty-git heatmap . --format jsonJSON: an array of buckets for (day-of-week × hour) with commit counts. CSV example:
dow,hour,commits
1,10,5
1,11,7
🈺 languages — languages
pretty-git languages . --format md --limit 10Determines language distribution in a repository. Supports multiple metrics: bytes, files, loc (default: bytes). Output includes language, selected metric column, and percent share; console shows language colors.
Console example:
Languages for .
language bytes percent
-------- ---------- -------
Ruby 123456 60.0
JavaScript 78901 38.3
Markdown 1200 1.7
Notes:
-
Detection: by file extensions and certain filenames (
Makefile,Dockerfile). -
Exclusions: binary files and "vendor"-like directories are ignored. By default
vendor/,node_modules/,.git/, build artifacts and caches are skipped. For Python projects additional directories are skipped:.venv/,venv/,env/,__pycache__/,.mypy_cache/,.pytest_cache/,.tox/,.eggs/,.ruff_cache/,.ipynb_checkpoints/. -
JSON: JSON is included as a language. If large data files skew results, consider narrowing with
--path/--exclude-path. -
Path filters: use
--path/--exclude-path(glob patterns supported) to focus on relevant areas. -
Limit:
--limit Nrestricts number of rows;0/all— no limit. -
Console colors: language names use approximate GitHub colors;
--no-colordisables,--theme monomakes output monochrome.
See also: Ignored directories and files.
Export:
- CSV/MD: columns are dynamic —
language,<metric>,percent. Markdown also includes acolorcolumn. - JSON/YAML/XML: full report structure including per-language
colorand metadata (report,generated_at,repo_path).
⚠️ hotspots — hotspots (risky files)
pretty-git hotspots . --format csv --limit 20Highlights riskier files combining change frequency and magnitude.
CSV columns: path,score,commits,additions,deletions,changes.
Example:
path,score,commits,additions,deletions,changes
lib/a.rb,9.5,12,300,220,520
app/b.rb,7.1,8,140,60,200
JSON example:
{
"report": "hotspots",
"generated_at": "2025-01-31T00:00:00Z",
"repo_path": ".",
"items": [
{"path": "lib/a.rb", "score": 9.5, "commits": 12, "additions": 300, "deletions": 220, "changes": 520}
]
}🔄 churn — code churn by file
pretty-git churn . --format md --limit 20Measures code churn (amount of code changing frequently).
CSV columns: path,churn,commits,additions,deletions.
Markdown example:
| path | churn | commits | additions | deletions |
|---|---:|---:|---:|---:|
| lib/a.rb | 520 | 12 | 300 | 220 |YAML example:
report: churn
generated_at: '2025-01-31T00:00:00Z'
repo_path: .
items:
- path: lib/a.rb
churn: 520
commits: 12
additions: 300
deletions: 220🏷️ ownership — code ownership
pretty-git ownership . --format csv --limit 50Shows file ownership concentration per primary owner.
CSV columns: path,owner,owner_share,authors.
Notes:
-
owner: author identifier (name/email) with the largest share of edits. -
owner_share: percent of edits by the owner (0..100). -
authors: total unique authors who edited the file.
XML example:
<?xml version="1.0" encoding="UTF-8"?>
<report>
<report>ownership</report>
<generated_at>2025-01-31T00:00:00Z</generated_at>
<repo_path>.</repo_path>
<items>
<item>
<path>lib/a.rb</path>
<owner>Alice <a@example.com></owner>
<owner_share>82.5</owner_share>
<authors>2</authors>
</item>
</items>
</report>📤 Exports
Below are exact serialization rules for each format to ensure compatibility with common tools (Excel, BI, CI, etc.).
🖥️ Console
Example terminal output (theme: basic).
-
Colors: headers and table heads highlighted; totals:
commits— yellow,+additions— green,-deletions— red.--no-colorfully disables coloring. -
Themes:
--theme basic|bright|mono.bright— more saturated headers,mono— monochrome (same as--no-color). - Highlight max: numeric columns underline max values in bold for quick scanning.
-
Terminal width: table output respects terminal width; first column is gracefully truncated with ellipsis
…if needed. - Encoding: UTF‑8, LF line endings.
- Purpose: human-readable terminal output.
- Layout: boxed tables, auto-truncation of long values.
🧾 JSON
-
Keys:
snake_case. - Numbers: integers/floats without localization (dot decimal separator).
-
Boolean:
true/false; null:null. -
Date/time: ISO8601 in UTC, e.g.
2025-01-31T00:00:00Z. -
Order: fields arranged logically and consistently (e.g.,
report,generated_at,repo_path, then data). - Encoding/line endings: UTF‑8, LF.
-
Suggested extension:
.json. -
Example:
{"report":"summary","generated_at":"2025-01-31T00:00:00Z","totals":{"commits":123}}
🧾 Schemas and Examples
Machine-readable examples and schemas live under docs/export_schemas/ and docs/examples/.
-
Schemas: see
docs/export_schemas/README.mdfor JSON and XML schema notes. -
Examples: example payloads for JSON/XML for each report under
docs/examples/. - Intended use: validation in CI, contract documentation, and integration tests.
CSV
- Structure: flat table, first line is header.
- Encoding: UTF‑8 without BOM.
-
Delimiter: comma
,. - Escaping: RFC 4180 — fields with commas/quotes/newlines are enclosed in double quotes, double quotes inside are doubled.
-
Empty values: empty cell (not
null). - Numbers: no thousand separators, dot as decimal.
- Date/time: ISO8601 UTC.
- Column order: fixed per report and stable.
- Line endings: LF.
-
Suggested extension:
.csv. - Excel: specify UTF‑8 on import.
-
Example:
author,author_email,commits,additions,deletions,avg_commit_size Alice,a@example.com,2,5,1,3.0 Bob,b@example.com,1,2,0,2.0
📝 Markdown
- Tables: GitHub Flavored Markdown.
-
Alignment: numeric columns are right-aligned (
---:). - Encoding/line endings: UTF‑8, LF.
-
Suggested extension:
.md. -
Empty datasets: header-only table or a short
No datamessage (depends on report). -
Example:
| path | commits | additions | deletions | |---|---:|---:|---:| | app/models/user.rb | 42 | 2100 | 1400 |
📄 YAML
- Structure: full result hierarchy.
- Keys: serialized as strings.
-
Numbers/boolean/null: standard YAML (
123,true/false,null). - Date/time: ISO8601 UTC as strings.
- Encoding/line endings: UTF‑8, LF.
-
Suggested extension:
.ymlor.yaml. -
Example:
report: authors generated_at: "2025-01-31T00:00:00Z" items: - author: Alice author_email: a@example.com commits: 2 - author: Bob author_email: b@example.com commits: 1
🗂️ XML
-
Structure: elements correspond to keys; arrays — repeated
<item>or specialized tags. - Attributes: for compact rows (e.g., files report) main fields may be attributes.
- Text nodes: used for scalar values when needed.
-
Escaping:
& < > " 'per XML rules; CDATA may be used for arbitrary text. - Date/time: ISO8601 UTC.
-
Encoding/line endings: UTF‑8, LF; declaration
<?xml version="1.0" encoding="UTF-8"?>may be added by the generator. -
Suggested extension:
.xml. -
Example:
<authors> <item author="Alice" author_email="a@example.com" commits="2" /> <item author="Bob" author_email="b@example.com" commits="1" /> <generated_at>2025-01-31T00:00:00Z</generated_at> <repo_path>/abs/path</repo_path> </authors>
🚫 Ignored directories and files
To keep language statistics meaningful, certain directories and file types are skipped by default.
Directories ignored (any path segment matching one of these):
vendor, node_modules, .git, .bundle, dist, build, out, target, coverage,
.venv, venv, env, __pycache__, .mypy_cache, .pytest_cache, .tox, .eggs, .ruff_cache,
.ipynb_checkpoints
Binary/data extensions ignored:
.png, .jpg, .jpeg, .gif, .svg, .webp, .ico, .bmp,
.pdf, .zip, .tar, .gz, .tgz, .bz2, .7z, .rar,
.mp3, .ogg, .wav, .mp4, .mov, .avi, .mkv,
.woff, .woff2, .ttf, .otf, .eot,
.jar, .class, .dll, .so, .dylib,
.exe, .bin, .dat
These lists mirror the implementation in lib/pretty_git/analytics/languages.rb and may evolve.
🔁 Determinism and Sorting
Output is deterministic given the same input. Sorting for files/authors: by changes (desc), then by commits (desc), then by path/name (asc). Limits are applied after sorting; all or 0 means no limit.
⚡ Performance Tips
- Prefer narrowing by
--path/--exclude-pathand--since/--untilon large repositories. - Use multiple
--branchonly when you explicitly want to include several heads; otherwise rely on currentHEAD. - For CI, cache the repository and fetch shallow history if full history is unnecessary for your report.
🤖 CI Usage
Examples for common pipelines:
# GitHub Actions (excerpt)
jobs:
reports:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.4'
- run: gem install pretty-git
- run: pretty-git authors . --format json --out authors.json
- uses: actions/upload-artifact@v4
with:
name: authors-report
path: authors.json🪟 Windows Notes
Primary targets — macOS/Linux. Windows is supported best‑effort. See detailed notes in docs/windows.md.
Highlights:
- Running via Git Bash/WSL is recommended.
- CRLF output from git is handled by the parser; exports use UTF‑8 with LF.
- Path filters are normalized to Unicode NFC when available; otherwise pass‑through.
- Colors can be disabled by
--no-coloror--theme mono.
🩺 Diagnostics and Errors
Typical issues and solutions:
-
Unknown report/format — check the first argument and
--format. -
Debugging — add
--verboseto see the effectivegit logcommand and applied filters. -
Invalid date format — use ISO8601 or
YYYY-MM-DD(e.g.,2025-01-31or2025-01-31T12:00:00Z). -
Git not available — ensure
gitis installed and in thePATH. -
Empty result — check your filters (
--since/--until,--branch,--path); your selection might be too narrow. - CSV encoding issues — files are saved as UTF‑8; when opening in Excel, pick UTF‑8.
❓ FAQ
- Why Ruby 3.4+? The project uses dependencies aligned with Ruby 3.4+ and targets the current ecosystem.
-
New formats? Yes, add a renderer under
lib/pretty_git/render/and wire it in the app. -
Where does data come from? From system
gitvia CLI calls.
🛠️ Development
# Install deps
bin/setup
# Run tests and linter
bundle exec rspec
bundle exec rubocopStyle — RuboCop clean. Tests cover aggregators, renderers, CLI, and integration scenarios (determinism, format correctness).
For detailed testing strategy, determinism rules, and golden tests workflow (how to run/update snapshots), see docs/testing.md.
📄 License
MIT © Contributors
