Beautiful git viewer in your browser โ like GitHub, but local. Diffs, history, blame, compare branches/SHAs, contributors, and more.
Project description
git-diff ๐
Beautiful git viewer in your browser โ like GitHub, but local and instant.
No tokens. No accounts. No internet. Justgit-diffand a browser tab.
The problem
$ git diff HEAD~3
diff --git a/src/api/users.py b/src/api/users.py
index 3f2a1b8..9c4d72e 100644
--- a/src/api/users.py
+++ b/src/api/users.py
@@ -142,6 +142,9 @@ class UserService:
...
Raw git diff in a terminal is painful โ no syntax colors that actually help, no side-by-side view, no file navigation, no history, no blame. You have to mentally parse it line by line.
git-diff opens a GitHub-quality interface in your browser โ right now, from any repo, with no setup.
Install
pip install git-diff
That's it. No npm, no node, no extra deps.
Usage
# Open viewer for the current repo
cd /path/to/your/project
git-diff
# Specify a repo path
git-diff --path /path/to/repo
# Use a custom port
git-diff --port 8080
# Bind to all interfaces (share on LAN)
git-diff --host 0.0.0.0
# Don't auto-open browser (print URL only)
git-diff --no-browser
# Show 5 lines of context in diffs
git-diff --context 5
# Print version
git-diff --version
A browser tab opens automatically at http://127.0.0.1:7433.
Features
๐ Diff Viewer (GitHub-style)
- Line-by-line diff with line numbers, color-coded
+additions /-deletions - Hunk headers showing function/class context (
@@ ... @@ def my_function) - File status badges โ Added, Modified, Deleted, Renamed (with similarity %)
- Collapsible files โ click any file header to expand/collapse
- Binary file detection
- Support for thousands of changed files in a single view
๐ Repository Overview
- Total commits, contributors, files, branches, tags, repo size
- Commit activity heatmap (last 90 days, GitHub-style calendar)
- Language breakdown โ files and percentage by extension with color chart
๐ Commit History
- Browse all commits with author, date, relative time ("3 hours ago")
- Click any commit to see its full diff instantly
- Merge commit detection
- Parent commit links (click to navigate)
- Ref decoration โ branch labels, HEAD pointer, tags
- Search and filter commits in the sidebar
๐ Compare Any Two Refs
- Compare any branch vs branch, tag vs tag, SHA vs SHA, or any mix
- Shows all commits in the range + full file diff
- One-click "Diff vs current" button on every branch in the branches panel
- Keyboard shortcut:
Ctrl/Cmd + K
โ๏ธ Working Tree Changes
- Staged and Unstaged changes clearly separated
- Click any file in sidebar to jump to its specific diff
- Real-time (refresh to update)
๐ File Browser
- Browse all tracked files
- View file content with syntax-aware line numbers
- File history โ all commits that touched a file
- Blame view โ who wrote which line, with commit hash and date
- Filter by filename in sidebar
๐ฅ Contributors
- Ranked leaderboard by commit count
- Visual progress bars
- Email address, commit count
๐ฟ Branches & Tags
- All local and remote branches
- Tags with dates and annotation messages
- "Diff vs current" button on every branch
๐ฆ Stashes
- View all stashed changes
- Click to see full diff for any stash entry
๐จ 3 Themes
| Theme | Description |
|---|---|
| ๐ Dark | GitHub dark โ easy on the eyes |
| โ๏ธ Light | GitHub light โ clean and crisp |
| โซ AMOLED | True black โ perfect for OLED screens |
Themes are persisted in localStorage โ your preference sticks across sessions.
โจ๏ธ Keyboard Shortcuts
| Shortcut | Action |
|---|---|
Esc |
Return to overview |
Ctrl/Cmd + R |
Refresh repository data |
Ctrl/Cmd + K |
Open Compare view |
Ctrl/Cmd + \ |
Toggle sidebar |
How it works
git-diff is a single Python package with zero runtime dependencies. It:
- Detects your git repository root (walks up from CWD)
- Collects all data by running
gitsubprocess commands - Starts a tiny HTTP server using Python's built-in
http.server - Serves a single-page web app with full UI
- Opens your browser automatically
- Exposes a
/api/*REST endpoint for on-demand data
Everything runs 100% locally. No data leaves your machine.
API Reference
git-diff exposes these endpoints (accessible at http://127.0.0.1:7433):
| Endpoint | Description |
|---|---|
GET / |
The web UI |
GET /api/data |
Full initial data bundle (repo info, commits, diffs, etc.) |
GET /api/commit?hash=<sha> |
Commit diff + detail for a specific SHA |
GET /api/commits?branch=&limit=&offset=&search=&author= |
Paginated commit history |
GET /api/staged[?context=N] |
Current staged diff |
GET /api/unstaged[?context=N] |
Current unstaged diff |
GET /api/range-diff?base=<ref>&compare=<ref> |
Diff between any two refs |
GET /api/file?path=<path>[&ref=<ref>] |
File content at a ref |
GET /api/file-log?path=<path>[&limit=N] |
Commit history for a file |
GET /api/blame?path=<path>[&ref=<ref>] |
Blame for a file |
GET /api/stash?ref=<stash-ref> |
Stash diff |
GET /api/activity[?days=N] |
Commit activity by day |
GET /api/langs |
Language statistics |
GET /api/refresh |
Re-collect all data |
GET /api/git?cmd=<git-args> |
Safe read-only git passthrough |
Supported git commands (internal)
git-diff internally uses these git operations to collect data:
git rev-parse โ detect repo root, resolve refs
git log โ commit history, activity stats, file history
git show โ commit detail, file content at ref
git diff โ staged, unstaged, commit diffs
git status โ working tree status
git blame โ line-level authorship
git stash list/show โ stash entries and diffs
git branch โ local and remote branches
git for-each-ref โ tags with metadata
git shortlog โ contributor stats
git ls-tree โ tracked file listing
git remote โ remote URLs
git rev-list โ commit counts
Supported Platforms
| Platform | Status |
|---|---|
| macOS (10.14+) | โ Fully supported |
| Linux (Ubuntu, Debian, Fedora, Archโฆ) | โ Fully supported |
| Windows 10/11 | โ Fully supported |
| Python 3.8 โ 3.13 | โ Tested via CI |
Development
# Clone the repo
git clone https://github.com/ankit-chaubey/git-diff.git
cd git-diff
# Install in editable mode
pip install -e .
# Run on itself โ great for testing!
git-diff
Project structure
git-diff/
โโโ git_diff/
โ โโโ __init__.py Package metadata (version, author)
โ โโโ __main__.py python -m git_diff support
โ โโโ cli.py Argument parsing, startup banner
โ โโโ git_data.py All git data collection (subprocess calls)
โ โโโ server.py HTTP server + REST API endpoints
โ โโโ templates/
โ โโโ index.html Full single-page web app (HTML + CSS + JS)
โโโ .github/
โ โโโ workflows/
โ โโโ publish.yml PyPI trusted publisher (OIDC)
โ โโโ ci.yml CI: test on 3 OS ร 5 Python versions
โโโ pyproject.toml PEP 517 build config
โโโ README.md
โโโ CHANGELOG.md
โโโ LICENSE MIT
Publishing to PyPI (for maintainers)
This project uses PyPI Trusted Publisher (OIDC) โ no API token or password required!
One-time setup
-
Create the package on PyPI (first release only):
- Go to pypi.org/manage/account/publishing
- Add a new pending trusted publisher:
PyPI project name : git-diff Owner : ankit-chaubey Repository name : git-diff Workflow filename : publish.yml Environment name : pypi
-
Create
pypienvironment in your GitHub repo:- Go to repo โ Settings โ Environments โ New environment โ name it
pypi - Optionally add a required reviewer for extra safety
- Go to repo โ Settings โ Environments โ New environment โ name it
Publishing a new release
Option A โ GitHub Release (recommended)
- Go to GitHub repo โ Releases โ Draft new release
- Create a tag like
v0.2.0 - Publish the release
- Workflow runs automatically โ published to PyPI โ
Option B โ Manual workflow dispatch
- Go to Actions โ "Publish to PyPI" โ Run workflow
- Enter optional new version (e.g.
0.2.0) โ auto-bumps and commits - Check "Dry run" to test without actually publishing
Changelog
See CHANGELOG.md.
License
MIT ยฉ 2024 Ankit Chaubey
Author
Ankit Chaubey
๐ง ankitchaubey.dev@gmail.com
๐ github.com/ankit-chaubey
Made with โค๏ธ because raw git diff in terminal hurts.
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 git_diff-0.1.2.tar.gz.
File metadata
- Download URL: git_diff-0.1.2.tar.gz
- Upload date:
- Size: 36.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
82befa47a8643ca4451acbc5fe7e9dacd12117054c7ed9c3e84113c6ffc88d8a
|
|
| MD5 |
d80098e17bb0ed7fa9985ea3ef89c730
|
|
| BLAKE2b-256 |
af86927cf7957bc6f2f3c211a6559c30c70ed78ade2ad7302788ac46a393c58e
|
Provenance
The following attestation bundles were made for git_diff-0.1.2.tar.gz:
Publisher:
publish.yml on ankit-chaubey/git-diff
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
git_diff-0.1.2.tar.gz -
Subject digest:
82befa47a8643ca4451acbc5fe7e9dacd12117054c7ed9c3e84113c6ffc88d8a - Sigstore transparency entry: 967365122
- Sigstore integration time:
-
Permalink:
ankit-chaubey/git-diff@b97476f23a2c1ad2d67f3ccf2c6898b2d958f399 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ankit-chaubey
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b97476f23a2c1ad2d67f3ccf2c6898b2d958f399 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file git_diff-0.1.2-py3-none-any.whl.
File metadata
- Download URL: git_diff-0.1.2-py3-none-any.whl
- Upload date:
- Size: 37.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2d4c5de1b23a9eb6e02365abf8012ae3355c541e6decc1ee2941b6ee28ed1ac0
|
|
| MD5 |
4e5ea9030c97f5c3bc04d541e9f164c8
|
|
| BLAKE2b-256 |
c5438868532cb608093fd220586b966c9160a94693333bdf43ff43855f36e8f8
|
Provenance
The following attestation bundles were made for git_diff-0.1.2-py3-none-any.whl:
Publisher:
publish.yml on ankit-chaubey/git-diff
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
git_diff-0.1.2-py3-none-any.whl -
Subject digest:
2d4c5de1b23a9eb6e02365abf8012ae3355c541e6decc1ee2941b6ee28ed1ac0 - Sigstore transparency entry: 967365189
- Sigstore integration time:
-
Permalink:
ankit-chaubey/git-diff@b97476f23a2c1ad2d67f3ccf2c6898b2d958f399 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ankit-chaubey
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b97476f23a2c1ad2d67f3ccf2c6898b2d958f399 -
Trigger Event:
workflow_dispatch
-
Statement type: