Skip to main content

Transform Git diffs into rich, interactive, self-contained HTML reports

Project description

DiffStory

Transform Git diffs into rich, interactive, self-contained HTML reports.

PyPI version Python versions License PyPI downloads

Understand not just what changed, but who changed it, when, and why — all offline, in a single portable file.

pip install diffstory
cd my-repo
diffstory --staged
# Opens a .html in your browser

Screenshots

Overview Inline View Blame Tooltip Side By Side Statistics Dashboard Unified View Evolution / Provenance

Why DiffStory?

Reading a diff in your terminal works — until it doesn't.

Tool Limitation
git diff Plain text, no navigation, no blame context, no sharing.
git blame Standalone per-file, disconnected from the diff. Requires the repository.
diff2html HTML output but no blame, no offline sharing, no analytics, no search.
PR reviews Tied to GitHub/GitLab. No offline access. Cannot be archived or emailed.

DiffStory combines git diff, git blame, and git log into a single interactive HTML report — no server, no accounts, no data leaving your machine.


Features

Feature Description
Unified View Classic git-style diff with line numbers and syntax highlighting.
Side-by-Side View Original (left) and modified (right) columns, visually aligned.
Inline View Word-level diff — green additions and red strikethrough removals on one line.
Blame Integration Hover any line for author, commit, subject, and relative time. Click for full commit details.
Provenance Metadata Author, date, commit message, files changed, insertions, deletions — per commit.
Search Global search across file names, authors, commit subjects, and code content.
Filters Narrow by file extension (.py, .js, .html) or change type (added, deleted, modified, renamed).
Statistics Floating dashboard with file counts, add/delete deltas, author breakdown, and top changed files.
Dark Mode Instant toggle, persists across sessions.
Offline Reports All CSS, JS, and data embedded. Works in any modern browser with zero network access.
Single HTML Output One file — no assets, no server, no dependencies.
Portable Sharing Email, archive, attach to a PR, or file for compliance. No repository access needed to view.

Additional Capabilities

  • Keyboard navigationJ/K to move between files, F or / to search, U/S/I to switch views
  • Deep linking#file-0 or #L-0-42 links to specific files and lines
  • Binary file detection — Image previews and metadata placeholders
  • Export formats — JSON, Markdown, and CSV alongside HTML (--json, --md, --csv)
  • Review mode — Per-file checkboxes with localStorage persistence (--review)
  • Config file~/.diffstory.toml or .diffstory.toml for persistent defaults

Installation

pip install diffstory

Requires: Python 3.10+ and Git.

From source:

git clone https://github.com/lakshayjindal/diffstory.git
cd diffstory
pip install -e .

Quick Start

# Working tree diff
diffstory

# Staged changes
diffstory --staged

# Commit comparison
diffstory HEAD~1 HEAD

# Branch comparison with path restriction
diffstory main feature/auth src/

# Custom output
diffstory -o report.html

# Generate from a diff file (no git repo needed)
diffstory --diff /path/to/patch.diff

# Multiple export formats
diffstory --staged --json --md --csv

What Makes DiffStory Different?

Feature git diff diff2html DiffStory
HTML report
Offline sharing
Blame / provenance
Line-level author info
Interactive navigation
Search across files
Filter by type / extension
Statistics dashboard
Dark mode
Keyboard shortcuts
Deep linking
Commit evolution slider
Risk analysis & hotspots
Single-file output
No runtime dependencies

Screenshots and Walkthrough

Overview

Overview

The main report screen. A sidebar lists all changed files with add/delete counts. The diff content area renders each file with its full change history. The toolbar gives access to view switching, search, theme, statistics, and the file list.

Why it matters: You get the full context of a changeset in one view — no scrolling between terminal windows or switching between git diff and git blame.

Unified View

Unified View

The default view. Lines are color-coded: green for additions, red for deletions. Line numbers for both old and new files are displayed side by side. Syntax highlighting is applied via Pygments.

Why it matters: Familiar to anyone who uses git diff, but with syntax highlighting and interactive features that the terminal cannot provide.

Side-by-Side View

Side By Side

Original file on the left, modified file on the right. Lines are aligned by position. Useful for understanding structural changes at a glance.

Why it matters: For large refactors or renames, seeing both versions side by side reveals patterns that a unified diff obscures.

Inline View

Inline View

Word-level diffs. Instead of showing a removed line and an added line, changed words are highlighted inline — removed text is struck through in red, added text is highlighted in green.

Why it matters: When a single word changes on a long line, finding the difference in a unified diff requires careful scanning. The inline view makes it obvious instantly.

Blame Tooltip

Blame Tooltip

Hover any changed line to see a tooltip with the author name, commit hash, commit subject, date, and relative time. Click the line to open a full commit detail drawer.

Why it matters: Answers "who wrote this line and why?" without leaving the report. No more switching to a terminal to run git blame.

Statistics Dashboard

Statistics Dashboard

A floating panel with file counts, add/delete deltas, author and commit counts, contributor breakdown, and a table of the most-changed files.

Why it matters: Gives an instant high-level summary of the changeset — useful for code reviews, release notes, and stakeholder updates.


Typical Use Cases

Use Case Description
Code Reviews Generate a report from a branch diff and share the link or file. Reviewers get interactive blame, search, and filtering — no GitHub/GitLab account required.
Release Reviews Before shipping, run diffstory v1.0..v2.0 to get a complete picture of everything that changed between releases.
QA Verification QA engineers can search for specific files, filter by change type, and inspect blame without CLI access.
Client Deliverables Share a self-contained HTML report with clients or stakeholders. They see exactly what changed without needing access to your repository.
Audit Trails Archive reports for compliance. Every report is a timestamped, self-contained document with full provenance.
Code Archaeology Trace who changed what and when in a specific file or function across commits.
Historical Investigations Run diffstory on any range of commits to reconstruct the evolution of a feature or bug fix.

Architecture

diffstory/                      # PyPI package
├── cli.py                      # Argument parsing, orchestration
├── git_utils.py                # Git subprocess wrappers (diff, blame, log)
├── diff_parser.py              # Unified diff → structured data
├── syntax.py                   # Pygments syntax highlighting
├── html_generator.py           # Self-contained HTML generation
└── generators/
    ├── get_css.py              # All CSS (inline)
    └── get_js.py               # All JavaScript (inline)
  • Python 3.10+ — Zero external Python dependencies except Pygments (for syntax highlighting).
  • Git CLI — All Git operations go through subprocess. No GitPython dependency.
  • Self-contained HTML — CSS, JavaScript, and data (blame, commits, search index) are embedded directly. No assets to serve, no network requests.
  • Offline-first — Everything runs locally. Generated reports work without internet access, indefinitely.

Philosophy

DiffStory is not trying to replace GitHub, GitLab, Bitbucket, or Git itself.

It exists to solve a specific problem: creating portable, shareable, interactive change reports that work anywhere, independent of infrastructure.

  • Reports are static files. Open them in any browser. Email them. Archive them. Attach them to tickets.
  • No accounts. No servers. No data leaves your machine.
  • The report answers the five questions reviewers actually ask: What changed? Who changed it? When? Why? How did it evolve?

Roadmap

Ideas for future releases — nothing guaranteed:

  • Annotations & comments — Inline commenting on specific lines, saved to the report
  • PDF export — Print-quality report generation
  • Diff comparison — Compare two reports side by side
  • Plugin system — Custom analyzers and visualizations
  • WebSocket live reload — Watch file changes and regenerate reports automatically
  • Language-specific analysis — TypeScript type changes, Rust borrow checker impact, etc.
  • Team review workflows — Aggregate reviews from multiple team members

Contributing

Contributions are welcome. The project is small and the codebase is straightforward.

  • Issues — Bug reports, feature requests, and questions.
  • Pull requests — Please open an issue first to discuss the change.
  • Local developmentpip install -e . for editable install. Run diffstory --staged in any repo to test.
git clone https://github.com/lakshayjindal/diffstory.git
cd diffstory
pip install -e .
diffstory --staged -o /tmp/test.html

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

diffstory-1.1.3.tar.gz (52.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

diffstory-1.1.3-py3-none-any.whl (51.0 kB view details)

Uploaded Python 3

File details

Details for the file diffstory-1.1.3.tar.gz.

File metadata

  • Download URL: diffstory-1.1.3.tar.gz
  • Upload date:
  • Size: 52.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for diffstory-1.1.3.tar.gz
Algorithm Hash digest
SHA256 e4eed98667c85801ec31784fc50db1a2c17727c6cda70488d250b6f026567440
MD5 f5e383a7550d86d1a209aaa58a17d9bd
BLAKE2b-256 a335f8449b47977b2901879c9e7567de138c0718b86fa545398373f29456ada4

See more details on using hashes here.

File details

Details for the file diffstory-1.1.3-py3-none-any.whl.

File metadata

  • Download URL: diffstory-1.1.3-py3-none-any.whl
  • Upload date:
  • Size: 51.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for diffstory-1.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 27154a8d01de5c9bff601579c37ec4751dc30c801c1a41ba0178d4273a5f38f0
MD5 023c1291102d23beb36cb94ffbe6a0cb
BLAKE2b-256 5f5df148cf5e9b7692181a18fa509bbeead964a006bb703709472a7abb034d7b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page