Transform Git diffs into rich, interactive, self-contained HTML reports
Project description
DiffStory
Transform Git diffs into rich, interactive, self-contained HTML reports.
DiffStory turns any git diff into a beautiful, portable HTML report that answers not just what changed, but who changed it, when, and why — all offline, in a single file you can share, archive, or email.
pip install diffstory
cd my-repo
diffstory --staged -o review.html
# Open review.html in any browser — zero setup required
Features
Three Diff Views
| View | Description |
|---|---|
| Unified | Classic git-style diff with line numbers and syntax highlighting |
| Side-by-Side | Original (left) and modified (right) columns, visually aligned |
| Inline Edit | Word-level diff — shows exact token changes inline, green additions and red strikethrough removals. No more mental diffing. |
Switch between views instantly with the toolbar or keyboard shortcuts — no regeneration needed.
Blame & Provenance
Every changed line carries its history. Hover any line to see a tooltip with author name, commit hash, subject, date, and relative time (e.g. "2h ago"). Click any line to open the commit drawer — a side panel with full metadata: commit body, author, committer, parents, files changed, insertions, and deletions.
Search & Filtering
- Global search — find files by name, author, commit subject, or code content with live results
- Filter chips — narrow the view by file extension (
.py,.js,.html, etc.) or change type (added, deleted, modified, renamed) - File sidebar — searchable file list with add/delete indicators and collapse/expand
Statistics Dashboard
A floating panel showing:
- Files changed, additions, deletions
- Added / deleted / modified / renamed file counts
- Author count and commit count (from blame)
- Contributor breakdown with commit counts
- Top 10 most-changed files
Keyboard Navigation
| Key | Action |
|---|---|
J / K |
Next / previous file |
F or / |
Focus global search |
U / S / I |
Unified / Side-by-side / Inline view |
D |
Toggle light/dark theme |
Esc |
Close drawer → close search → close stats |
Deep Linking
Link directly to specific files and lines: #file-0 scrolls to the first file, #L-0-42 scrolls to line 42 in the first file. Shareable, stable anchors.
Binary File Support
Binary files are detected and displayed with meaningful placeholders — image files get a preview icon, other binaries show metadata — preventing crashes and keeping the report clean.
Customization
- Light/Dark themes — toggle instantly, persists across sessions
- Config file —
~/.diffstory.tomlor.diffstory.tomlin your project sets defaults for verbose mode, debug output, and more --verbose/--debugflags — see what's happening under the hood
Export Formats
Alongside the HTML report, export structured data:
diffstory --staged --json --md --csv
Installation
pip install diffstory
Requires: Python 3.10+ and Git.
To install from source:
git clone https://github.com/lakshayjindal/diffstory.git
cd diffstory
pip install -e .
Usage
# Working tree diff
diffstory
# Staged changes (what will be committed)
diffstory --staged
# Compare commits
diffstory HEAD~3 HEAD
# Compare branches
diffstory main feature-branch
# Compare revisions with path restriction
diffstory HEAD~3 HEAD src/
# Generate from a diff file directly (no git repo needed)
diffstory --diff /path/to/patch.diff
# Custom output file
diffstory -o my-review.html
# Multiple export formats at once
diffstory --staged --json --md --csv -o release-v2.0
# Verbose mode
diffstory --staged --verbose
# Show version
diffstory --version
Config File Example
Create ~/.diffstory.toml or .diffstory.toml in your project:
[cli]
verbose = true
debug = false
HTML Report
Every generated HTML report is fully self-contained:
- All CSS inlined — no external stylesheets
- All JavaScript inlined — no external scripts
- All data (blame, commits, search index) embedded as JSON
- Works offline in any modern browser
- Safe to email, archive, or include in audit evidence
- Zero external dependencies at runtime
Open it, share it, attach it to a PR, or file it for compliance. It just works.
Project Structure
diffstory/
├── pyproject.toml # Build config & CLI entry point
├── README.md
├── requirements.md # Full product requirements & spec
├── deploy.sh # Build & publish script
├── .github/workflows/publish.yml # CI/CD for PyPI publishing
├── src/diffstory/
│ ├── __init__.py # Package version
│ ├── __main__.py # python -m diffstory support
│ ├── cli.py # CLI argument parsing & orchestration
│ ├── git_utils.py # Git subprocess wrappers (diff, blame, log)
│ ├── diff_parser.py # Unified diff parser → structured data
│ ├── syntax.py # Pygments syntax highlighting
│ └── html_generator.py # Self-contained HTML report generation
└── tests/
└── __init__.py
Development
# Install in editable mode
pip install -e .
# Test with a quick repo
cd /tmp && mkdir test-diffstory && cd test-diffstory
git init && echo "hello" > test.py && git add -A && git commit -m "init"
echo "world" >> test.py
diffstory --staged
# Build the package
python -m build
# Deploy (version bump, build, publish)
./deploy.sh # patch bump
./deploy.sh minor # minor bump
Design Philosophy
DiffStory was built to answer five questions about every changed line:
What changed? Who changed it? When? Why? How did it evolve?
It consolidates git diff, git blame, git log, and GitHub-style review UX into a single, portable artifact — no server, no accounts, no data leaving your machine.
Security
- Never uploads code or transmits data
- No telemetry, no analytics, no accounts
- No external API calls by default
- Never modifies your repository
- Generated reports are safe for air-gapped environments, client deliverables, and compliance audits
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file diffstory-0.3.0.tar.gz.
File metadata
- Download URL: diffstory-0.3.0.tar.gz
- Upload date:
- Size: 34.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
554d395cc215be577562bf5625a5f0d00cdc8bb126eb923cd749163ebd55d29a
|
|
| MD5 |
a0e726acd91328a590a409d18d43c4f8
|
|
| BLAKE2b-256 |
51ae9ecefa10d016aefb55eef5552e880dcf1d419550ea6a032df9d12a41acb8
|
File details
Details for the file diffstory-0.3.0-py3-none-any.whl.
File metadata
- Download URL: diffstory-0.3.0-py3-none-any.whl
- Upload date:
- Size: 33.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
83ae9f779c188175349a91f8254ff7c8396b6b4f15b96150c2d1a9b9fb0267f6
|
|
| MD5 |
9069f88064a923be623bef77915c503a
|
|
| BLAKE2b-256 |
38258ef3d5740adaaf505b42301f618fd0aba1e21f897b36f075eab781c0e861
|