magit-project-diff-mode

magit-project-diff-mode: identity marker for the project-diff view — every changed file as one editable multibuffer.

On this page

An identity marker for the project-diff view: every changed file in the working tree, composed into one multibuffer you can edit.

The gap it fills

Magit already diffs in two shapes and neither is this one. The status buffer's sections are patch text built for staging; *magit:diff:<repo>:<path>* reads well but is one file at a time, and is still patch text. Missing was every changed file at once, as real source you can edit — you spot a typo in file 19 of a 30-file review, and otherwise you must leave the diff, open the file, fix it, and come back.

Editable, when the thing being compared is a file

An excerpt is a hunk's range in the working-tree file, so editing it lands in the file through the ordinary propagation pipeline — no patch application, no separate write-back.

That anchoring is also the limit. Only the working tree is a file:

ComparisonView
working tree vs HEADeditable
working tree vs indexeditable
index vs HEAD (staged)read-only

An index blob is not a file, so there is nothing for an edit to land in. Those comparisons open read-only and the headerline says which you are looking at. That is the correct rendering of a comparison between two things that are not the file on disk, rather than a degraded mode.

What happens to the colours once you edit

Fix something in an excerpt and that file's + colouring, gutter marks and grey deleted-line rows go away, and the headerline gains a note:

[project-diff: working tree] 12 hunks in 5 files · 1 edited file — gr to refresh

That is deliberate. The diff was computed against the file as it was when the view opened; the moment you insert a line, every mark below your edit describes the line above or below the one it is drawn on. The view would rather show you no diff colouring for a file it can no longer describe than colouring that is quietly one row out.

Only the file you edited loses its colouring — the other four in the example keep theirs. gr re-scans and brings it all back, including your edit as part of the diff.

Folding a large diff

The view has two levels of structure, so :set foldlevel=0 collapses it to one row per file and :set foldlevel=1 to one row per hunk. On a fifty-file review that is the difference between a list and a wall.

Keybindings

None of its own. It joins the magit family and takes the family's chords: gr (re-scan, keeping whichever comparison you are looking at), q, and ]] / [[ to walk file boundaries.

It joins magit-nav-mode rather than magit-core-mode, which matters here: core's single letters (i, C, D, S, U, yr) are meant for read-only lists, and in a buffer you can type in, i has to mean Insert.

See also

  • magit — the rest of the family.
  • multibuffer — excerpts, jumping, editing.
  • foldingfoldlevel and the fold chords.