Documentation
Complete reference for revdiff usage, configuration, themes, keybindings, the pi package, and the Claude Code plugin.
Requirements
git is used to generate diffs. It is optional when using --only for standalone file review or --stdin for scratch-buffer review.
Installation
Homebrew (macOS/Linux)
brew install umputun/apps/revdiffBinary releases
Download from GitHub Releases — deb, rpm, archives for linux/darwin amd64/arm64.
Pi package
revdiff also ships as a pi package. The extension launches the existing revdiff binary, captures annotations on exit, and keeps them visible inside pi as a persistent widget plus a right-side results panel.
pi install https://github.com/umputun/revdiffCommands inside pi
/revdiff -- detect uncommitted, staged, or branch changes, then open revdiff
/revdiff HEAD~1 -- review last commit
/revdiff --all-files -- browse all tracked files
/revdiff --only README.md -- review a single file in context-only mode
/revdiff --pi-overlay -- use the existing overlay launcher script
/revdiff-rerun -- rerun the last review with remembered args
/revdiff-rerun --pi-overlay -- rerun the last review in overlay mode
/revdiff-results -- reopen the last results panel
/revdiff-apply -- insert the last annotations into the pi chat context
/revdiff-clear -- clear stored review state
/revdiff-reminders on -- enable post-edit review remindersRequires the revdiff binary on PATH. Set REVDIFF_BIN=/absolute/path/to/revdiff if pi can’t find the binary. Same-terminal mode is the default. Optional overlay mode (--pi-overlay or REVDIFF_PI_MODE=overlay) reuses the existing launch-revdiff.sh script from the Claude plugin integration. Optional post-edit reminders (/revdiff-reminders on) suggest running /revdiff or /revdiff-rerun after agent edits.
Usage
revdiff [OPTIONS] [base] [against]Positional arguments support several forms:
revdiff— uncommitted changesrevdiff HEAD~3— diff a single ref against the working treerevdiff main feature— diff between two refsrevdiff main..feature— same as above, git dot-dot syntaxrevdiff main...feature— changes since feature diverged from main
Examples
# review uncommitted changes
revdiff
# review changes against a branch
revdiff main
# review staged changes
revdiff --staged
# review last commit
revdiff HEAD~1
# diff between two refs
revdiff main feature
# review only specific files
revdiff --only=model.go --only=README.md
# browse all git-tracked files
revdiff --all-files
# browse all files, excluding vendor and mocks
revdiff --all-files --exclude vendor --exclude mocks
# exclude paths in normal diff mode
revdiff main --exclude vendor
# same as above, git dot-dot syntax
revdiff main..feature
# review a standalone file (no git needed)
revdiff --only=/tmp/plan.md
# review a file with no git changes (context-only)
revdiff --only=docs/notes.txt
# review piped text as a scratch buffer
printf '# Plan\n\nBody\n' | revdiff --stdin --stdin-name plan.md
# capture annotations from generated output
some-command | revdiff --stdin --output /tmp/annotations.txtAll-files mode
Use --all-files (or -A) to browse all git-tracked files, not just files with changes. This turns revdiff into a general-purpose code annotation tool. All files are shown in context-only mode with full annotation and syntax highlighting support.
--all-files requires a git repository (uses git ls-files) and is mutually exclusive with refs, --staged, and --only. Combine with --exclude (or -X) to filter by prefix.
--exclude uses prefix matching: --exclude vendor skips vendor/, vendor/foo.go, etc. It works in both --all-files and normal diff modes.
revdiff --all-files --exclude vendor --exclude mocksPersist in config: exclude = vendor. Or env: REVDIFF_EXCLUDE=vendor,mocks.
Context-only file review
When --only specifies a file that has no git changes (or when no git repo exists), revdiff shows the file in context-only mode: all lines displayed without +/- markers, with full annotation and syntax highlighting support.
- Inside a git repo — files not in the diff are read from disk alongside changed files
- Outside a git repo —
--onlyis required; files are read directly from disk
Scratch-buffer review
Use --stdin to review arbitrary piped or redirected text as a single synthetic file. All lines are treated as context, so the normal single-file review flow still works: annotations, file-level notes, search, wrap, collapsed mode, and structured output.
--stdin is explicit, requires piped or redirected input, and is mutually exclusive with refs, --staged, --only, --all-files, and --exclude.
Use --stdin-name to control the synthetic filename for annotation output and extension-based highlighting or markdown TOC activation.
echo "plain text" | revdiff --stdin
printf '# Plan\n\nBody\n' | revdiff --stdin --stdin-name plan.md
git show HEAD~1:README.md | revdiff --stdin --stdin-name README.mdMarkdown TOC navigation
When reviewing a single markdown file in context-only mode, a table-of-contents pane appears on the left listing all markdown headers. This works for --only files and for --stdin when --stdin-name ends with .md or .markdown. Use Tab to switch focus, j/k to navigate, Enter to jump. The TOC highlights the current section as you scroll. Headers inside fenced code blocks are excluded.
Beyond code review
The --only and --stdin flags enable use cases beyond git diffs. Files and ephemeral command output can both be loaded for annotation, no git repo required.
Reviewing AI-generated drafts — When an AI assistant drafts text to be posted publicly (PR comments, issue responses, release notes), write it to a temp file and review in revdiff. Annotate specific lines, the assistant rewrites, re-open to verify.
Reviewing documentation and specs — Markdown files, API specs, config files, and plan documents can all be reviewed with inline annotations.
revdiff --only=docs/plans/feature.md
revdiff --only=/tmp/draft-comment.mdReviewing generated output — CI configs, Terraform plans, generated migrations — anything that needs human review before being applied.
Config file
Location: ~/.config/revdiff/config (INI format). Override with --config flag or REVDIFF_CONFIG env var.
Precedence: CLI flags > env vars > config file > built-in defaults.
mkdir -p ~/.config/revdiff
revdiff --dump-config > ~/.config/revdiff/configOptions
| Option | Description | Default |
|---|---|---|
--staged | Show staged changes | false |
--tree-width | File tree width in units (1-10) | 2 |
--tab-width | Spaces per tab character | 4 |
--no-colors | Disable all colors | false |
--no-status-bar | Hide the status bar | false |
--wrap | Enable line wrapping | false |
--collapsed | Start in collapsed diff mode | false |
--cross-file-hunks | Allow [ and ] to continue into adjacent files | false |
--line-numbers | Show line numbers in diff gutter | false |
--no-confirm-discard | Skip discard confirmation | false |
--chroma-style | Syntax highlighting theme | catppuccin-macchiato |
--theme | Load color theme from ~/.config/revdiff/themes/ | |
--dump-theme | Print resolved colors as theme file and exit | |
--list-themes | Print available theme names and exit | |
--init-themes | Write bundled theme files to themes dir and exit | |
-A, --all-files | Browse all git-tracked files | false |
--stdin | Review stdin as a scratch buffer | false |
--stdin-name | Synthetic file name for stdin content | scratch-buffer |
-X, --exclude | Exclude files by prefix (repeatable) | |
-F, --only | Show only matching files | |
-o, --output | Write annotations to file | |
--keys | Path to keybindings file | ~/.config/revdiff/keybindings |
--dump-keys | Print effective keybindings and exit | |
--config | Path to config file | ~/.config/revdiff/config |
--dump-config | Print default config and exit | |
-V, --version | Show version info |
Themes
Five bundled color themes: catppuccin-mocha, dracula, gruvbox, nord, and solarized-dark. Stored in ~/.config/revdiff/themes/, auto-created on first run.
revdiff --theme dracula # apply a theme
revdiff --list-themes # list available
revdiff --init-themes # re-create bundled themes
revdiff --dump-theme > ~/.config/revdiff/themes/my-customSet default in config: theme = dracula. Or env: REVDIFF_THEME=dracula.
Creating custom themes
Two approaches:
- From current colors: customize individual colors via config or
--color-*flags, then dump:revdiff --dump-theme > ~/.config/revdiff/themes/my-custom - From scratch: copy a bundled theme and edit directly. Each file defines all 21 color keys plus
chroma-stylein INI format:
# name: my-custom
# description: custom color scheme
chroma-style = dracula
color-accent = #bd93f9
color-border = #6272a4
...all 21 color keys...Precedence
Without --theme: built-in defaults → config file → env vars → CLI flags.
When --theme is set, it takes over completely: all 21 color fields and chroma-style are overwritten, ignoring any --color-* flags or env vars. --theme + --no-colors prints a warning and applies the theme.
Color customization
All color options accept hex values (#rrggbb) and have REVDIFF_COLOR_* env vars.
| Option | Description | Default |
|---|---|---|
--color-accent | Active borders, directory names | #D5895F |
--color-border | Inactive borders | #585858 |
--color-normal | File entries, context lines | #d0d0d0 |
--color-muted | Dividers, status bar | #585858 |
--color-selected-fg | Selected file text | #ffffaf |
--color-selected-bg | Selected file background | #D5895F |
--color-annotation | Annotation text and markers | #ffd700 |
--color-cursor-fg | Cursor indicator color | #bbbb44 |
--color-cursor-bg | Cursor indicator background | terminal default |
--color-add-fg/bg | Added line text / background | #87d787 / #123800 |
--color-remove-fg/bg | Removed line text / background | #ff8787 / #4D1100 |
--color-modify-fg/bg | Modified line (collapsed mode) | #f5c542 / #3D2E00 |
--color-status-fg/bg | Status bar | #202020 / #C5794F |
--color-search-fg/bg | Search matches | #1a1a1a / #4a4a00 |
--color-tree-bg | File tree background | terminal default |
--color-diff-bg | Diff pane background | terminal default |
Chroma syntax highlighting styles
Set via --chroma-style, env REVDIFF_CHROMA_STYLE, or config chroma-style = name.
Dark themes
aura-theme-dark, aura-theme-dark-soft, base16-snazzy, catppuccin-frappe, catppuccin-macchiato (default), catppuccin-mocha, doom-one, doom-one2, dracula, evergarden, fruity, github-dark, gruvbox, hrdark, monokai, modus-vivendi, native, nord, nordic, onedark, paraiso-dark, rose-pine, rose-pine-moon, rrt, solarized-dark, solarized-dark256, tokyonight-moon, tokyonight-night, tokyonight-storm, vim, vulcan, witchhazel, xcode-dark
Light themes
autumn, borland, catppuccin-latte, colorful, emacs, friendly, github, gruvbox-light, igor, lovelace, manni, modus-operandi, monokailight, murphy, paraiso-light, pastie, perldoc, pygments, rainbow_dash, rose-pine-dawn, solarized-light, tango, tokyonight-day, trac, vs, xcode
Other
RPGLE, abap, algol, algol_nu, arduino, ashen, average, bw, hr_high_contrast, onesenterprise, swapoff
Navigation
| Key | Action |
|---|---|
j/k or arrows | Navigate files (tree) / scroll diff |
h/l | Switch between tree and diff pane |
Tab | Switch between panes |
left/right | Horizontal scroll in diff |
PgDown/PgUp | Page scroll |
Ctrl+d/Ctrl+u | Half-page scroll |
Home/End | Jump to first/last item |
Enter | Switch to diff (tree) / annotate (diff) |
n/p | Next/prev changed file or TOC header |
[ / ] | Jump to prev/next change hunk; with --cross-file-hunks, continues to prev/next file at the boundary |
Search
| Key | Action |
|---|---|
/ | Start search in diff pane |
n | Next search match (when search active) |
N | Previous search match |
Esc | Cancel search / clear results |
Annotations
| Key | Action |
|---|---|
a or Enter | Annotate current line |
A | Add file-level annotation |
@ | Toggle annotation list popup |
d | Delete annotation under cursor |
Esc | Cancel annotation input |
View toggles
| Key | Action |
|---|---|
v | Toggle collapsed diff mode |
w | Toggle word wrap |
t | Toggle tree/TOC pane visibility |
L | Toggle line numbers |
B | Toggle git blame gutter (author + commit age) |
. | Expand/collapse hunk (collapsed mode) |
f | Filter: all files / annotated only |
? | Help overlay |
q | Quit, output annotations |
Q | Discard annotations and quit |
Custom keybindings
All keybindings can be customized via ~/.config/revdiff/keybindings. Override path with --keys or REVDIFF_KEYS.
# ~/.config/revdiff/keybindings
map ctrl+d half_page_down
map ctrl+u half_page_up
map x quit
unmap qGenerate a template: revdiff --dump-keys > ~/.config/revdiff/keybindings
Modal keys (annotation input, search input, confirm discard) are not remappable.
Available actions
Navigation: down, up, page_down, page_up, half_page_down, half_page_up, home, end, scroll_left, scroll_right
File/Hunk: next_item, prev_item, next_hunk, prev_hunk
Pane: toggle_pane, focus_tree, focus_diff
Search: search
Annotations: confirm, annotate_file, delete_annotation, annot_list
View: toggle_collapsed, toggle_wrap, toggle_tree, toggle_line_numbers, toggle_hunk, filter
Quit: quit, discard_quit, help, dismiss
Claude Code plugin
revdiff ships with a Claude Code plugin for interactive code review directly from a Claude session. The plugin launches revdiff as a terminal overlay, captures annotations, and feeds them back to Claude for processing.
# add marketplace and install
/plugin marketplace add umputun/revdiff
/plugin install revdiff@umputun-revdiffTerminal support
The plugin requires one of the following terminals since Claude Code itself cannot display interactive TUI applications. The overlay runs revdiff in a separate terminal layer on top of the current session.
| Terminal | Overlay method | Detection |
|---|---|---|
| tmux | display-popup (blocks until quit) | $TMUX |
| zellij | zellij run --floating | $ZELLIJ env var |
| kitty | kitty @ launch --type=overlay | $KITTY_LISTEN_ON |
| wezterm | wezterm cli split-pane | $WEZTERM_PANE |
| kaku | kaku cli split-pane (same API as wezterm) | $WEZTERM_PANE |
| cmux | cmux new-split + cmux send | $CMUX_SURFACE_ID |
| ghostty | AppleScript split + zoom (macOS only) | $TERM_PROGRAM |
| iTerm2 | AppleScript split pane (macOS only) | $ITERM_SESSION_ID |
| Emacs vterm | New frame via emacsclient | $INSIDE_EMACS |
Priority: tmux → zellij → kitty → wezterm/kaku → cmux → ghostty → iTerm2 → Emacs vterm (first detected wins). cmux is checked before ghostty because it also sets $TERM_PROGRAM=ghostty. iTerm2 uses a split pane rather than a full-screen overlay.
Plugin usage
Slash commands
/revdiff -- smart detection: uncommitted, last commit, or branch diff
/revdiff HEAD~1 -- review last commit
/revdiff main -- review current branch against main
/revdiff HEAD~3 -- review last 3 commits
/revdiff --staged -- review staged changes only
/revdiff all files -- browse all tracked filesNatural language
"review diff" -- same as /revdiff, smart detection
"review diff HEAD~1" -- last commit
"review diff against main" -- branch diff
"review changes from last 2 days" -- Claude resolves the ref
"revdiff for staged changes" -- staged only
"review all files exclude vendor" -- browse project, skip vendor/
"what themes does revdiff support?" -- ask about config without launching
"switch revdiff to dracula theme" -- modify config via conversationThe plugin includes built-in reference documentation and can answer questions about revdiff usage, themes, keybindings, and configuration. It can also create or modify the local config file on request.
The plugin supports the full review loop: annotate → plan → fix → re-review until no more annotations remain.
Auto-detection
When no ref is provided, the plugin detects what to review automatically:
- On main/master with uncommitted changes — reviews uncommitted changes
- On main/master with clean tree — reviews the last commit
- On a feature branch with clean tree — reviews branch diff against main
- On a feature branch with uncommitted changes — asks whether to review uncommitted only or the full branch diff
Plan review plugin
A separate revdiff-planning plugin automatically opens revdiff when Claude exits plan mode, letting you annotate the plan before approving it. If you add annotations, Claude revises the plan and asks again, looping until you're satisfied.
/plugin install revdiff-planning@umputun-revdiffThis plugin is independent from the main revdiff plugin and does not conflict with other planning plugins.
Output format
On quit, revdiff outputs annotations to stdout (or file via --output):
## handler.go (file-level)
consider splitting this file into smaller modules
## handler.go:43 (+)
use errors.Is() instead of direct comparison
## handler.go:43-67 (+)
refactor this hunk to reduce nesting
## store.go:18 (-)
don't remove this validationEach annotation block: ## filename:line[-end] (type) where type is (+) added, (-) removed, or (file-level); -end is included when the annotation covers a line range.
When annotation text contains the keyword “hunk” (case-insensitive, whole word), the output header automatically expands to include the full hunk line range (e.g., handler.go:43-67 (+) instead of handler.go:43 (+)). This gives AI consumers the range context without any extra steps.
Integration with other tools
The structured stdout output works with any tool that can read text:
# capture annotations for processing
annotations=$(revdiff main)
if [ -n "$annotations" ]; then
echo "$annotations" | your-tool
fi