diffman is a terminal UI for reviewing git diffs and attaching per-line review comments.
It is built with Bubble Tea and designed for fast keyboard-driven review.
diffman-recording.mp4
- File tree for all changed files in the current repository.
- Side-by-side diff view with syntax-like coloring and word-level change highlighting.
- Per-line comments stored locally per repository.
- Inline comment display in the diff panes.
- Comment list view across all files.
- Export comments to clipboard in a review-friendly format.
- Leader key commands (
<space><key>) configurable via user config.
- Go
1.26+ git- A terminal with Unicode/color support
Build and install into ~/.local/bin:
make installOther targets:
make run
make build
make test
make lintRun diffman anywhere inside a git repository:
diffmandiffman discovers the repository root automatically and shows changed files.
The app has three views:
- Files view: directory tree + changed files.
- Diff view: old/new diff panes (or single pane for one-sided diffs).
- Comments view: all comments across files.
Focus moves with tab.
tab: switch focus (files -> diff -> comments)m: toggle comments viewr: refresh files/diff statet: toggle diff mode (all,unstaged,staged)C: clear all comments (with confirmation)<space><key>: run configured leader command?: toggle expanded helpq: quit (except in comments view, where it closes comments view)
j/k: move selection (diff updates immediately)ctrl+e/ctrl+y: scroll file tree windowh: parent/collapse behaviorl: child/expand behavior; on file, focus diff viewenter: open file diff; on directory, toggle collapsez: toggle file pane width (40<->120)
Directory navigation behavior:
- On a file,
hgoes to its parent directory. - On an expanded directory,
hcollapses it. - On a collapsed directory,
hgoes to parent. - On a directory,
lexpands and jumps to first direct child.
j/k: move diff cursorctrl+e/ctrl+y: scroll window by one linectrl+f/ctrl+b: page down/upg/G: top/bottomc: add comment on current linee: edit comment on current lined: delete comment on current linen/p: jump next/previous comment in current diffy: copy exported comments to clipboardzorl: hide/show file paneh: focus files view
j/k: movectrl+e/ctrl+y: scroll window by one linectrl+f/ctrl+b: page down/upg/G: top/bottomenter: jump to selected comment in diff (if not stale)e: edit selected commentd: delete selected commentmorq: close comments view
Comments are saved in the repo git directory:
.git/.diffman/comments.json
Each comment is anchored by:
- file path
- side (
oldornew) - line number
diffman shows inline comment text beneath the commented line in diff panes.
A comment is marked stale when its anchor can no longer be found in current diff output.
Behavior:
- Stale comments are marked in comments view.
- Jumping to stale comments is disabled.
- Stale comments are excluded from clipboard export.
- A warning appears in the footer when stale comments exist.
Toggle with t:
all: default, includes all changesunstaged: unstaged onlystaged: staged only
For one-sided changes:
- New file: only the
Newpane is shown. - Deleted file: only the
Oldpane is shown.
Configure custom command shortcuts in:
$HOME/.config/diffman/config.json- or
$XDG_CONFIG_HOME/diffman/config.jsonifXDG_CONFIG_HOMEis set
Format:
{
"leader_commands": {
"g": "lazygit",
"o": "code \"$ROOT/$FILE\""
}
}Rules:
- Keys must be exactly one character.
- Values are shell commands.
- Commands run via
$SHELL -lc '<command>'.
Environment variables provided to leader commands:
ROOT: absolute repository rootFILE: currently selected file path (repo-relative)
After a leader command exits, diffman auto-refreshes file/diff state.
y copies non-stale comments in this style:
Review comments:
1) path/to/file.go new:21: Comment text
With context block per comment when available.
diffmanonly shows files reported as changed bygit status.- Running outside a git repository will fail at startup.
- If config parsing fails, the app still starts and shows an alert.