Skip to content
adizaimiPublic

About

Tool to view git diff across versions of a given file. Open a file in Neovim and step backward/forward through its git history with a key combination, staying positioned on the same function across versions so the change is visible as a diff. This is like vimdiff on steroids for git history viewing.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

18 Commits

Folders and files

Repository files navigation

vhist

Open a file in Neovim and step backward/forward through its git history with a key combination, staying positioned on the same function across versions so the change is visible as a diff. This is like vimdiff on steroids for git history viewing.

vhist opened on a file, before any navigation vhist diffing the current file against an earlier commit
Just opened — normal Neovim, plus a one-time message reporting how many revisions the file has. After Alt-Left — a vertical diffthis split against an earlier commit, with each pane's statusline naming what it's showing instead of a throwaway file path.

Both screenshots are real vhist sessions, running on files from this repo's own history.

Requirements

  • Go 1.21+
  • git
  • nvim (Neovim; drives the editor)
  • ctags — must be Universal Ctags, not the BSD ctags shipped with macOS. On macOS: brew install universal-ctags neovim. Without it, vhist still works but falls back to plain line-number navigation instead of tracking the enclosing function.

Build

go build -o vhist ./cmd/vhist

Usage

./vhist --line 42 path/to/file.go

Inside Neovim:

  • Alt-Left (<M-Left>) — jump to the previous revision of the file
  • Alt-Right (<M-Right>) — jump to the next revision
  • Alt-Up (<M-Up>) — toggle what each revision is diffed against: its parent commit (default) or the current file on disk
  • Alt-Down (<M-Down>) — toggle line numbers on both panes (or run :VhistNumbers, handy where Alt/Option keys don't reach nvim, e.g. macOS Terminal, where Option+letter is a dead key)
  • :q — quit vhist. The diff is two panes in one Neovim; a lone :q/:q!/:wq is expanded to quit both at once, so a single quit leaves the editor.

(Plain-letter combos like <leader>[ and bare function keys like <F7> were tried first: <leader>-based ones get silently re-bound by language-server on_attach hooks or treesitter-textobjects FileType autocmds — a buffer-local mapping always wins over a global one, so on e.g. Go files gopls's own binding for the same keys would shadow vhist's; bare function keys are often intercepted as OS media keys or mangled by the terminal. Alt+arrow avoids both. vhist also reasserts its binding buffer-locally on every LspAttach/FileType event, so it can't be shadowed later either. To check what's bound to a key in a given buffer: :verbose nmap <M-Left>.)

Each jump shows one commit's own change to the file as a vertical diffthis split: the revision on the right, its immediate predecessor in the file's history on the left (the oldest revision reads as the file's creation, with an empty left pane). So stepping back through history shows a different, self-contained diff at each commit rather than an accumulating diff against your current file. The cursor is repositioned to the same enclosing function/symbol when it can be found in ctags output for that revision (falling back to the same line number otherwise).

Press Alt-Up to switch the left pane to the current file on disk instead of the parent commit — i.e. "how does this old version differ from what I have now" — and again to switch back. The toggle redraws the revision already onscreen, so you keep your place.

Browser view

For a GitHub-style diff in a browser instead of Neovim:

./vhist --view web path/to/file.go

This starts a small HTTP server bound to 127.0.0.1 on a random port and opens the page in your default browser. Each commit that touched the file is a step on a timeline you walk with the ←/→ arrow keys (or the sidebar): each step shows what that commit changed to the file, the oldest revision reads as the file's creation, and a final "working tree" step shows any uncommitted changes against HEAD. Toggle between side-by-side and unified layouts in the header. Press Ctrl-C in the terminal to stop the server.

The web view is a second frontend over the same history.Provider the editor uses; it needs no editor and no ctags. Requests carry a per-session token so another local process can't read your file's history off the port. git is the diff engine (git diff --no-index), and the renderer (diff2html) is embedded in the binary via go:embed, so there is no Node.js, network access, or separate asset directory at runtime.

Status

v1: git only. Two frontends — Neovim (--view editor, the default) and a browser diff view (--view web). See internal/history, internal/editor, internal/symbol, internal/app, and internal/webview for the component breakdown.

About

Tool to view git diff across versions of a given file. Open a file in Neovim and step backward/forward through its git history with a key combination, staying positioned on the same function across versions so the change is visible as a diff. This is like vimdiff on steroids for git history viewing.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages