Skip to content
Download

DOCS / GIT

Reading diffs

One diff viewer serves the whole app — the Changes and Review tabs, commit diffs in History, PR file lists, and the branch-compare dialog. This page is the single reference for its controls, so workflow pages can stay task-focused and link here.

Until a file is selected, the pane shows Select a file to view its diff.

The Side-by-side toggle in the diff header switches between the two layouts:

  • Unified (the default) — additions and deletions interleaved in one column. Best for small edits and for reading a change top-to-bottom.
  • Side-by-side — old version left, new version right. Best for dense rewrites, where you want to compare the two states of a line rather than read a patch.
  • Ignore whitespace re-runs the diff with git diff -w, hiding indentation-only and trailing-whitespace changes. Handy after a reformat.
  • Diff lines are syntax-highlighted by file type, using the same dark color theme as the rest of the app.
  • Changed line pairs get word-level highlighting: the exact words that differ within a modified line are emphasized, so a one-token edit doesn’t read as a whole rewritten line. Lines longer than 2000 characters skip the word-level pass (minified files would make it needlessly expensive).

Git’s default diff shows 3 lines of context around each hunk. GitHub-style expander rows let you reveal the unchanged lines in between — above the first hunk, between hunks, and below the last one. What each expander offers depends on the size of the hidden gap:

Hidden linesExpander controls
Up to 20⋯ Show all N hidden lines
21–40↑ Show 20 · ⋯ Show all N hidden lines · ↓ Show 20
More than 40↑ Show 20 lines · ── N hidden lines ── · ↓ Show 20 lines

Large gaps deliberately have no “show all”: revealing thousands of lines at once would freeze the pane, so you expand toward the code you care about 20 lines at a time. Below the last hunk, the expander reads ↓ Show more lines until the file’s length is known.

Two cases have no expanders at all: brand-new files (including untracked ones) and deleted files — there is no hidden context on one side to reveal. Expanders also disappear if the file on disk no longer matches the diff (it changed since the diff was taken), rather than splicing in wrong lines.

For an unstaged working-tree file, a strip above the diff lists each hunk as a button — Discard hunk: Hunk 1, Hunk 2, … — with the hunk’s @@ header as its tooltip. Clicking one reverts just that hunk on disk and refreshes the diff.

When a file has both staged and unstaged changes, the viewer shows everything since HEAD — the file’s total change, not just the index — and says so with a staged + unstaged badge in the header. See Commit changes for why the tri-state staging model requires this.

  • Images render as a Before / After pair side by side. An added or deleted image shows (none) on the missing side.
  • Other binary files fall back to Binary file — cannot display.
SurfaceWhat it diffs
Changes tabWorking-copy changes per file (with hunk discard)
Review tabEverything a workspace changed vs its base branch
History tabA selected commit’s files
PR file listsA pull request’s changed files (no entry point in the current build — see Review and manage PRs)
Compare branchesFiles differing between two branches (no entry point in the current build)