vscode-diff Next — compare branches and repos side by side

Compare any two Git endpoints — two branches of one repo, or branches of two
different repos in a multi-root workspace — with a changed-file tree, commit
history, and one-click built-in diffs, all in a dedicated sidebar.
vscode-diff Next is the actively maintained product on top of the classic
Diff Visualizer lineage. The
upstream git history stays in this repo so the fork trail is honest. Packaging,
security posture, docs, and day-to-day tooling follow the same bar as
vscode-pdf Next.

Why this extension?
- 🔀 Branch compare without leaving the editor. Pick two endpoints
(
{folder} · {ref}); see every changed path and the commits between them.
- 🗂️ Cross-repo compare. Each side can be a different repository in your
workspace — ideal for comparing versioned checkouts (
app-2.5 vs app-2.6)
that don't share a git history.
- ✅ Honest file status. Status comes from
git diff --name-status
(A/M/D/R/C, NUL-safe parsing, rename detection) — not guessed from
insert/delete counts. Renamed files diff old name ↔ new name.
- 🕘 Commit history. Searchable list for the
base..target range; subject
and body exactly as git wrote them.
- 🔒 Hardened. Nonce-based webview CSP, untrusted-input validation on every
ref and path crossing the webview boundary, no shell execution
(refs and paths are passed to git as discrete arguments).
Features
| Feature |
Status |
| Dual targets: any two workspace repos + branches |
✅ |
| Session tabs: hold several compares at once |
✅ |
| Folder-then-branch picker (searchable, not a short OS list) |
✅ |
| SCM-style list (M / U / D / R / C) with foldable groups |
✅ |
| M → side-by-side diff; U/D → single side; R → old ↔ new |
✅ |
| Images and PDFs open in their viewer, changed ones side by side |
✅ |
| Open Target 2 worktree file (↗) |
✅ |
| Editable diff + per-change revert arrow (→) when Target 2 is checked out |
✅ |
| Discard: apply Target 1 → Target 2 worktree (binary-safe) |
✅ |
| Commit history + search (same-repo only, capped at 1000) |
✅ |
| Persist open tabs + last pair + list font size |
✅ |
| Unicode / unusual filenames |
✅ (-z parsing) |
| Windows / Linux / macOS |
✅ (git on PATH) |
Getting started
Requires VS Code 1.95+ and Git on PATH. For the install scripts, the
VS Code CLI (code) must be on PATH too. Prebuilt VSIX files are attached to
GitHub Releases.
From this repo
Windows (PowerShell):
cd path\to\vscode-diff-next
npm install
.\update-extension.ps1
# or: .\update-extension.ps1 -NoRestart
Linux / macOS:
cd path/to/vscode-diff-next
npm install
chmod +x ./update-extension.sh
./update-extension.sh
# or: ./update-extension.sh --no-restart
Cross-platform npm wrappers: npm run update, npm run update:norestart,
npm run update:dev.
Dev loop (Extension Development Host, no VSIX):
npm run update:dev
# other terminal: npm run watch
# Extension Host: Reload Window after each change
From a VSIX
npm run compile
npm run package # bundles production deps (simple-git); do not use --no-dependencies
code --install-extension diff-next-<version>.vsix --force
Marketplace id once published: RicardoFrantz.diff-next.
Usage
- Click vscode-diff Next in the activity bar.
- Use tabs to keep more than one compare open (
+ adds a tab; each tab
is one pair). Drag a tab to reorder the strip, or Ctrl+Shift+← / → from
the keyboard — the order is remembered. Double-click (or F2) renames a tab;
clearing the name restores the folder · folder label. Right-click for
Rename, Duplicate, Close, Close others, and Close to the right.
- Pick each side with the folder-then-branch picker: click a target,
choose a workspace folder (type to filter), then a local branch of
that folder. A side that already has a folder starts on its branches, and so
does the second box once the first one has a folder — comparing two
branches of one repo is two clicks.
← goes back to folders, and an explicit
folder on that side is never overridden. A new tab starts on the folder you
were last in. Remotes are hidden. The two sides can never be the same
endpoint.
- Click a Modified (M) file for a side-by-side diff; Renamed (R) diffs
the old path against the new one. Under the two targets, Compare view
has independent on/off toggles (Wrap, Ignore spaces, Two columns, Fold
same, Pin tab, Moved code) plus Prev/Next file. They apply to the editor
that opens. The folder picker closes once you pick a branch.
- Click a New (U) or Deleted (D) file for a single view.
- Click a group header (Modified / New / Deleted / …) to fold that section.
- Same-repo only: searchable commit history between the tips.
↺ applies Target 1's version onto Target 2's worktree (with confirmation);
↗ opens the Target 2 worktree file.
Command Palette: vscode-diff Next: Compare Branches (editor-area panel).
To leave a note for Claude / Codex: select text in the compare or in any file
on disk. A strip opens on those lines: Save, then the five tags
(fix improve explain re-check discuss, with fix armed),
then Delete. Type the note — the armed tag rides in the box as {fix} —
and press Enter. Esc discards it. Clicking anywhere outside the selection hands
the keyboard straight back to the editor.
A saved range turns amber: the text is washed, the gutter gets a rail, the
scrollbar gets a mark, and a {fix} chip sits at the end of the range. It
reads on top of the green of an added line, so you can see at a glance which
parts of a diff you have already been through. Hover the amber to read the note
or delete it. The first save creates myfile-rev.json next to myfile.md.
Later notes append to the same file:
[
{
"selected_text": "the highlighted code\ncan span lines",
"range": "42-45",
"tag": "fix",
"comment": "your note"
}
]
Per-change revert arrows (like VS Code's own diff)
When Target 2 is the checked-out branch of its repository and the file
exists on disk, the diff opens against the working-tree file instead of a
read-only snapshot (the title ends in · Working Tree). That makes the right
side editable, so VS Code's built-in diff editor shows its native per-change
gutter arrow (→) — click it to revert just that change to Target 1's version,
then save (Ctrl+S) to persist. F7 / Shift+F7 (and the title-bar arrows)
jump between changes in any diff.
Notes:
- The arrow is VS Code's own
diffEditor.renderMarginRevertIcon (default on).
- The right side shows the file as it is on disk, including uncommitted
local edits; the file tree still lists changes between the two committed
refs, so a reverted-and-saved file stays listed until you commit.
- When neither target is checked out, diffs stay read-only snapshots as before.
Set
diff-next.diffAgainstWorktree: false to always get read-only diffs.
- The
+ (stage hunk) gutter button is exclusive to VS Code's built-in git
SCM views and can't appear in extension-opened diffs — save your revert,
then stage it from the Source Control view.
Security model
- No shell. All git invocations go through
simple-git with discrete
arguments — refs and paths are never interpolated into a command line.
- Untrusted webview input. Every ref and path received from the webview or
from virtual-document URIs is validated: refs must not look like git flags
(no leading
-, no git-forbidden characters); paths must be repo-relative
with no .. escapes. Worktree writes are additionally checked to resolve
inside the target repository root.
- Strict CSP. The webview allows only nonce-tagged scripts; error output is
rendered as text, never HTML.
- No telemetry, no network calls. Everything runs against your local repos.
See SECURITY.md for reporting.
Identity (same family as vscode-pdf Next)
|
vscode-pdf Next |
vscode-diff Next |
| Repository |
ricardofrantz/vscode-pdf-next |
ricardofrantz/vscode-diff-next |
| Display name |
vscode-pdf Next |
vscode-diff Next |
| Package name |
pdf-preview-next |
diff-next |
| Install id |
RicardoFrantz.pdf-preview-next |
RicardoFrantz.diff-next |
| Command prefix |
vscode-pdf Next: … |
vscode-diff Next: … |
Publisher for both: RicardoFrantz.
Development
See docs/DEVELOP.md. Short map:
src/host/DiffHost.ts shared webview host + git message handling
src/services/gitService.ts git façade via simple-git (-z parsers, validation)
src/webview/ UI (vanilla JS, injected into one HTML file)
update-extension.ps1/.sh compile → package → install → restart
Checks: npm run lint, npm run compile, npm run smoke:paths. CI runs all
three plus a VSIX package on Linux, macOS, and Windows. Releases are tag-driven
— see docs/RELEASING.md.
Coming from lixiaoliang.diff-visualizer?
Uninstall the old extension, install this one. Same job: two branches, file
tree, commits. New work lands here only.
Credits & license
Fork of Diff Visualizer
(lxliang912 / lkcoffee). See NOTICE and LICENSE.