Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

git-dashboard

A live-updating browser-based git status dashboard with word-level diff highlighting for macOS. Single Python file, no framework, no dependencies beyond Python 3 and git.

Word-level diff highlighting in git-dashboard — additions, deletions, and moved phrases each colored distinctly

Why

Standard git diff is line-level. Change a single curly quote in the middle of a paragraph and the entire paragraph is marked red and green — you squint to find the actual change. Fine for code. Awful for prose.

This tool generates an HTML dashboard that highlights exactly which words changed, in color, inline. It's especially useful when:

  • You're editing prose (long-form content, marketing copy, documentation, drafts).
  • You're working with AI assistants (Claude Code, Cursor, etc.) and want to see what they actually changed in a file the moment they save it.
  • You're reviewing commits before pushing and want a precise pre-commit read.

The AI-assisted-editing use case

Leave gd open in a Terminal tab and a browser tab while you work with Claude Code or any other AI assistant. When the assistant edits a file, the dashboard auto-refreshes within seconds — you see exactly which words were added, removed, or changed.

This collapses verification from "carefully re-read the whole paragraph to confirm the AI did what I asked" to "glance at the dashboard and confirm the colored words match your intent."

Install

Clone the repo and run the deploy script, which symlinks gd into ~/bin for casual typing:

git clone https://github.com/scottschram/git-dashboard.git
cd git-dashboard
script/deploy

The script is idempotent — safe to re-run any time. It repoints a stale gd link at the current checkout, refuses to overwrite a gd that isn't a symlink, and warns if ~/bin isn't on your PATH. To install somewhere else, set BIN_DIR:

BIN_DIR=~/.local/bin script/deploy

Prefer to do it by hand? The script is equivalent to:

chmod +x git-dashboard.py
ln -s "$PWD/git-dashboard.py" ~/bin/gd

Make sure ~/bin is on your PATH. Add to ~/.zshrc (or ~/.bashrc) if it isn't:

export PATH="$HOME/bin:$PATH"

Verify:

gd --help

Usage

gd                              # watch mode (default) — opens browser, auto-refreshes
gd --once                       # one-shot snapshot — opens browser, exits
gd --range HEAD~3..HEAD         # show a commit range (implies --once)
gd --range HEAD~3               # range + uncommitted working tree changes
gd /path/to/other/repo          # point at a different repo
gd --help                       # full options

In watch mode the dashboard polls every 5 seconds. When the repo state changes (status, HEAD, staged content, unstaged content, or upstream tracking ref), the browser tab refreshes automatically. Ctrl-C to stop the server.

The one-shot modes (--once, --range) write the dashboard HTML to /tmp/<repo-name>-git-dashboard.html and open it via file://. Useful in scripts and CI; the browser tab is static and won't auto-refresh.

When remote changes appear

The dashboard never fetches on an idle timer. git fetch runs in exactly two situations: when something changes locally (any edit, stage, or commit triggers a rebuild, which fetches first), and when you click the ↻ button.

In practice the remote-tracking info is fresh whenever you're actually working — every local edit piggybacks a fetch, so the ahead/behind counts and the main card keep up. The one stale case is a fully idle repo: you step away, a collaborator pushes, and the dashboard sits unchanged until your next edit or a manual ↻.

This is a deliberate trade-off, not an oversight. The alternative is hitting the network every minute, forever, from every open dashboard — and the event it would catch is not only rare but self-limiting. Suppose you come back from lunch, glance at a green dashboard, and commit anyway: the commit itself is a local change, so within seconds the dashboard rebuilds, fetches, and shows you're behind — before you've pushed. And if you push regardless, git rejects it as non-fast-forward and tells you to pull first. The stale dashboard can mislead you only while the repo sits untouched; the moment you act, it corrects itself, with git's push rejection as the backstop. Nothing is ever lost. If you're expecting a push, click ↻.

Requirements

  • macOS
  • Python 3 (uses only the standard library — no pip install)
  • git
  • A browser (uses your system default)

Tests

There's a pytest suite under tests/ — run it with:

script/test

script/test runs pytest through uvx (from uv) in an ephemeral, cached environment — no virtualenv to create, no pip install. Install uv first if you don't have it (brew install uv).

These are development-only dependencies. uv and pytest are needed only to run the tests — never to run the dashboard. The tool keeps the zero-dependency, standard-library-only runtime described under Requirements above; the test tooling doesn't touch it.

The suite covers the pure diff and parsing functions and the git-integration logic (via hermetic, offline temporary repositories), plus golden-master snapshots of the generated HTML. If an intentional change to the HTML updates those snapshots, re-bless them with UPDATE_GOLDENS=1 script/test -k golden and review the diff.

What the dashboard shows

  • Branch + tracking status (ahead / behind remote, in sync, no remote)
  • Last commit (hash, message, author, when)
  • Files changed in working tree, with per-file status (modified, added, deleted, staged)
  • Full diff of all changes, with word-level highlighting of additions, deletions, and substitutions within modified lines
  • In --range mode: the same diff view, but for committed history rather than the working tree

Following main while on a feature branch

When you're on any branch other than the default (main, master, etc.), the right column splits into two stacked cards so you can spot when main has moved underneath you:

  • ⎇ Branch — only the commits unique to your branch (origin/main..HEAD), capped at 12. The existing yellow highlight still marks unpushed commits.
  • 📜 main — recent commits on origin/main with a sync badge:
    • green In sync with main when your branch already contains everything on main
    • red ↓ N behind main when collaborators have pushed commits you don't have yet. Those commits appear at the top of the list with a salmon highlight. The count is accurate even if more than 12 commits are behind (the list is capped; the badge is not).

The bottom card lists up to 12 entries, with at most 6 "already in your branch" commits shown for orientation — the rest of the slots go to behind-by commits. If you're more than 12 commits behind main, it's probably time to rebase anyway.

The default branch is detected via git symbolic-ref refs/remotes/origin/HEAD, so it works for repos using master or trunk too. In a no-remote / scratch repo the dashboard falls back to a local main or master ref — useful when two terminal sessions share a repo and one of them commits on main while you work on a branch in the other. On the default branch itself, or in a repo with no detectable default, the right column stays as a single "📜 Recent Commits" card.

Opening Finder and Terminal

In watch mode the header and the changed-file list are interactive:

  • Click the Path in the header to open the repository folder in Finder.
  • Click the 🖥️ icon next to the Path to open a terminal at the repository root — handy for running project scripts like bin/verify deploy.
  • Click any changed file in the Working Tree Status panel to reveal that file in Finder, selected in its folder — handy for double-clicking it open in your editor, or in Preview for an image.

For safety, only the repository folder and files in the current change set can be opened this way; nothing else is reachable.

The terminal launcher uses Terminal.app by default. To use a different terminal, set the GIT_DASHBOARD_TERMINAL environment variable to its application name — for example, export GIT_DASHBOARD_TERMINAL=iTerm.

Finder shows the folder in whatever view it's configured to use, and macOS often defaults to Gallery or Icon view. If you'd rather land in List view, set it as your Finder default: switch a Finder window to List view, open View Options (⌘J), and click Use as Defaults.

These actions need the live server, so they work in watch mode only — the static --once / --range snapshots render the path and filenames as plain text.

License

MIT — see LICENSE.

About

A live-updating browser-based git status dashboard with word-level diff highlighting for macOS.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages