SIGN IN SIGN UP

fix(diff): default to POSIX normal format (#413)

`diff` emitted unified format with no flags, so `diff a b | grep '^<'` -
the canonical "lines only in A" idiom - silently matched nothing on files
that differ. `-u` was parsed and thrown away, `createTwoFilesPatch` was the
only output path, normal format was unreachable by any flag, and every
invocation was prefixed with jsdiff's 67-character `===...===` banner, which
is not valid output in any GNU format.

Normal format is now the default. `-u`/`--unified` selects unified,
`--normal` selects the default explicitly, `-c`/`--context` is new, and
`--version` is new. Two output styles at once is an error, as in GNU. The
banner is gone from every format, and the `-u`/`-c` headers carry no
timestamp so output stays reproducible. `\ No newline at end of file` is
reported in all three formats.

Filenames in `-u`/`-c` headers are quoted and escaped the way GNU does, so a
filename containing a newline cannot forge header or `@@` lines in the
emitted patch.

The formatters were written from the bytes GNU diffutils 3.12 emits, and the
new tests freeze that output verbatim for a single changed line, insertions
and deletions at every position, separated and merged hunks, empty files in
both directions, all three trailing-newline combinations and blank-line
context.

Edit-script selection is unchanged and still comes from the `diff` package.
Where several equally minimal scripts exist, hunk grouping may differ from
GNU: over 199 mutated source-file pairs, 149 unified diffs are byte-identical
to GNU, all 199 apply cleanly under `patch` to reproduce the target file, and
none differ from GNU in edit count.

`-q`, `-s`, `-i`, `-` for stdin and the exit codes are unchanged.

Fixes #412

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
L
Lars Trieloff committed
2d9d41fd90ad024cf54a7bc0caa345af7966c410
Parent: bbf3881
Committed by GitHub <noreply@github.com> on 9/7/2026, 8:00:40 PM