]> git.ipfire.org Git - thirdparty/git.git/commit
diff: consult diff process for --stat counts
authorMichael Montalbo <mmontalbo@gmail.com>
Sun, 26 Jul 2026 18:51:27 +0000 (18:51 +0000)
committerJunio C Hamano <gitster@pobox.com>
Sun, 26 Jul 2026 21:03:54 +0000 (14:03 -0700)
commit4c0cd15ffc3b18ca472316c846a5660dde3aa3fc
treef0a8b94872b5f82699ae91d5c1c4a3156200759f
parent149d3e3a12aabe8bcdb18f68ce16dd12e4804a07
diff: consult diff process for --stat counts

builtin_diff() already consults a configured diff.<driver>.process: a
file the tool reports as equivalent emits no patch, and otherwise the
tool's hunks drive the output.  builtin_diffstat() ran its own xdiff
and ignored the process, so "git diff --stat" still counted a
byte-level change for a file that "git diff" showed as unchanged.

Consult diff_process_fill_hunks() before the stat xdiff, as
builtin_diff() does.  On DIFF_PROCESS_EQUIVALENT, skip the xdiff so
the file keeps its zero inserted and deleted counts and the existing
"nothing changed" pruning drops it, matching the empty patch.
Otherwise the tool's hunks, or the builtin fallback, feed the counts
through the shared xpparam_t.

Under -L, route the surviving hunks through the same line-range filter
builtin_diffstat() already uses for a tracked range, so a
process-provided diff is scoped to that range: "git log -L<range>
--stat" counts the tool's changed lines within the range rather than
the builtin line diff's.

Like the builtin summary path, builtin_diffstat() does not apply
textconv, so the process is consulted on the raw blob content here,
unlike builtin_diff() which sends textconv'd content.  This keeps
"git diff --stat" counting raw lines as it does today; the asymmetry
between patch output and summary counts under textconv predates this
change.  Because the content is the raw blob, the stat path sends the
blob object names to the tool (old-oid/new-oid) for any stored blob,
where the patch path omits the oid under textconv.

Move the summary formats out of the "not yet wired" group of the
"Which features consult the diff process" documentation and into the
list of features that use the tool's hunks, noting the raw,
non-textconv content they receive.  Document that the line-counting
--dirstat=lines follows these counts while the default --dirstat does
not, and that summary formats and blame (only under --textconv) differ
from patch output in whether they textconv the content the tool sees.

Add tests covering counts from the tool's hunks (--numstat,
--shortstat), an equivalent file producing no stat line, --stat
--exit-code, the raw non-textconv content the tool receives, a
multi-file mix of equivalent and changed files, a mode-only change,
and a range-scoped --stat under "git log -L" that reflects the tool's
hunks.

Signed-off-by: Michael Montalbo <mmontalbo@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/gitattributes.adoc
diff.c
t/t4080-diff-process.sh