From dcf76b03aa6fe2839b35e8883000c76c585efadf Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Tue, 24 Feb 2026 10:53:46 +0000 Subject: [PATCH 1/2] doc: Remove misleading filterdiff rename example --- doc/patchutils.xml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/doc/patchutils.xml b/doc/patchutils.xml index b862571b..e925de8a 100644 --- a/doc/patchutils.xml +++ b/doc/patchutils.xml @@ -962,14 +962,7 @@ patch.file]]> Git format diffs are fully supported, including binary files, - file renames, and permission mode changes. For example, to extract - only the renames from a git diff: - - + file renames, and permission mode changes. See also From f2c9bf042366d7bb9bed724223041f91d8653f2f Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Wed, 25 Feb 2026 08:46:05 +0000 Subject: [PATCH 2/2] Use {braces} for tool-specific help filtering Change the help text filtering syntax from (parentheses) to {braces} to allow free use of parentheses and square brackets in help output. Previously, options ending with (toolname) were filtered to only show in specific tools (filterdiff, lsdiff, grepdiff), but this prevented using parentheses for natural purposes like "(default: keep)" or "(original-before or original-after)". Square brackets like "[OPTION]" are also common in CLI help text. Changes to src/filterdiff.c: - Parser now looks for {toolname} instead of (toolname) at line ends - All help text annotations changed from [toolname] to {toolname} - Filters applied to every line of multi-line options to prevent orphaned descriptions from appearing in wrong tools Changes to doc/patchutils.xml: - Added missing lsdiff options: --addoldprefix, --addnewprefix, -I/--include-from-file, -X/--exclude-from-file - Added missing grepdiff option: --empty-files-as-absent - Documented all options in both synopsis and description sections This ensures help output matches actual available options and allows natural use of punctuation in help text. Assisted-by: Claude Code --- doc/patchutils.xml | 49 +++++++++++++++++++++++++++ src/filterdiff.c | 84 +++++++++++++++++++++++----------------------- 2 files changed, 91 insertions(+), 42 deletions(-) diff --git a/doc/patchutils.xml b/doc/patchutils.xml index e925de8a..27bbb1dc 100644 --- a/doc/patchutils.xml +++ b/doc/patchutils.xml @@ -1079,6 +1079,8 @@ patch.file]]> --strip=n --git-prefixes=strip|keep --addprefix=PREFIX + --addoldprefix=PREFIX + --addnewprefix=PREFIX -s --status @@ -1091,10 +1093,18 @@ patch.file]]> -i PATTERN --include=PATTERN + + -I FILE + --include-from-file=FILE + -x PATTERN --exclude=PATTERN + + -X FILE + --exclude-from-file=FILE + -z --decompress @@ -1262,6 +1272,22 @@ patch.file]]> it. + + =PREFIX + + Prefix pathnames for old files with + PREFIX before displaying + them. + + + + =PREFIX + + Prefix pathnames for new files with + PREFIX before displaying + them. + + , @@ -1291,6 +1317,14 @@ patch.file]]> PATTERN. + + FILE, + + + Include only files matching any pattern listed in + FILE, one pattern per line. + + PATTERN, @@ -1299,6 +1333,14 @@ patch.file]]> PATTERN. + + FILE, + + + Exclude files matching any pattern listed in + FILE, one pattern per line. + + , @@ -2015,6 +2057,7 @@ This is the same as gitdiff but uses git show instead of git diff. -s --status + --empty-files-as-absent -i PATTERN --include=PATTERN @@ -2191,6 +2234,12 @@ This is the same as gitdiff but uses git show instead of git diff. !. + + + + Treat empty files as absent when matching patterns. + + PATTERN, diff --git a/src/filterdiff.c b/src/filterdiff.c index 4f8a6956..c7fb1326 100644 --- a/src/filterdiff.c +++ b/src/filterdiff.c @@ -1599,34 +1599,34 @@ const char * syntax_str = " --lines=L include only hunks with (original) lines in range L, if range begins with x show all excluding range L\n" " -F F, --files=F\n" " include only files in range F, if range begins with x show all excluding range F\n" -" --annotate (filterdiff, patchview, grepdiff)\n" -" annotate each hunk with the filename and hunk number (filterdiff, patchview, grepdiff)\n" -" --as-numbered-lines=before|after|original-before|original-after (filterdiff, patchview, grepdiff)\n" -" display lines as they would look before, or after, the patch is applied;\n" -" or with original line numbers from the diff (original-before/original-after)\n" -" --format=context|unified (filterdiff, patchview, grepdiff)\n" -" set output format (filterdiff, patchview, grepdiff)\n" -" --output-matching=hunk|file (grepdiff)\n" -" show matching hunks or file-level diffs (grepdiff)\n" -" --only-match=rem|removals|add|additions|mod|modifications|all (grepdiff)\n" -" regex will only match removals, additions, modifications or (grepdiff)\n" -" the whole hunk (grepdiff)\n" -" --remove-timestamps (filterdiff, patchview, grepdiff)\n" -" don't show timestamps from output (filterdiff, patchview, grepdiff)\n" -" --clean (filterdiff)\n" -" remove all comments (non-diff lines) from output (filterdiff)\n" -" --in-place (filterdiff)\n" -" write output to the original input files (filterdiff)\n" +" --annotate {filterdiff, patchview, grepdiff}\n" +" annotate each hunk with the filename and hunk number {filterdiff, patchview, grepdiff}\n" +" --as-numbered-lines=before|after|original-before|original-after {filterdiff, patchview, grepdiff}\n" +" display lines as they would look before, or after, the patch is applied; {filterdiff, patchview, grepdiff}\n" +" or with original line numbers from the diff (original-before or original-after) {filterdiff, patchview, grepdiff}\n" +" --format=context|unified {filterdiff, patchview, grepdiff}\n" +" set output format {filterdiff, patchview, grepdiff}\n" +" --output-matching=hunk|file {grepdiff}\n" +" show matching hunks or file-level diffs {grepdiff}\n" +" --only-match=rem|removals|add|additions|mod|modifications|all {grepdiff}\n" +" regex will only match removals, additions, modifications or {grepdiff}\n" +" the whole hunk {grepdiff}\n" +" --remove-timestamps {filterdiff, patchview, grepdiff}\n" +" don't show timestamps from output {filterdiff, patchview, grepdiff}\n" +" --clean {filterdiff}\n" +" remove all comments (non-diff lines) from output {filterdiff}\n" +" --in-place {filterdiff}\n" +" write output to the original input files {filterdiff}\n" " -z, --decompress\n" " decompress .gz and .bz2 files\n" -" -n, --line-number (lsdiff, grepdiff)\n" -" show line numbers (lsdiff, grepdiff)\n" -" -N, --number-files (lsdiff, grepdiff)\n" -" show file numbers, for use with filterdiff's --files option (lsdiff, grepdiff)\n" -" -H, --with-filename (lsdiff, grepdiff)\n" -" show patch file names (lsdiff, grepdiff)\n" -" -h, --no-filename (lsdiff, grepdiff)\n" -" suppress patch file names (lsdiff, grepdiff)\n" +" -n, --line-number {lsdiff, grepdiff}\n" +" show line numbers {lsdiff, grepdiff}\n" +" -N, --number-files {lsdiff, grepdiff}\n" +" show file numbers, for use with filterdiff's --files option {lsdiff, grepdiff}\n" +" -H, --with-filename {lsdiff, grepdiff}\n" +" show patch file names {lsdiff, grepdiff}\n" +" -h, --no-filename {lsdiff, grepdiff}\n" +" suppress patch file names {lsdiff, grepdiff}\n" " -p N, --strip-match=N\n" " initial pathname components to ignore\n" " --strip=N initial pathname components to strip\n" @@ -1639,25 +1639,25 @@ const char * syntax_str = " prefix pathnames in old files with PREFIX\n" " --addnewprefix=PREFIX\n" " prefix pathnames in new files with PREFIX\n" -" -s, --status (lsdiff, grepdiff)\n" -" show file additions (+), removals (-), and modifications (!) (lsdiff, grepdiff)\n" +" -s, --status {lsdiff, grepdiff}\n" +" show file additions (+), removals (-), and modifications (!) {lsdiff, grepdiff}\n" " -v, --verbose\n" " verbose output -- use more than once for extra verbosity\n" -" -E, --extended-regexp (grepdiff)\n" +" -E, --extended-regexp {grepdiff}\n" #ifdef HAVE_PCRE2POSIX_H -" this option has no effect as PCRE regexes are used by default (grepdiff)\n" +" this option has no effect as PCRE regexes are used by default {grepdiff}\n" #else -" use extended regexps, like egrep (grepdiff)\n" +" use extended regexps, like egrep {grepdiff}\n" #endif -" -E, --empty-files-as-absent (lsdiff)\n" -" treat empty files as absent (lsdiff)\n" -" --empty-files-as-absent (grepdiff)\n" -" treat empty files as absent (grepdiff)\n" -" -f FILE, --file=FILE (grepdiff)\n" -" read regular expressions from FILE (grepdiff)\n" -" --filter run as 'filterdiff' (grepdiff, patchview, lsdiff)\n" -" --list run as 'lsdiff' (filterdiff, patchview, grepdiff)\n" -" --grep run as 'grepdiff' (filterdiff, patchview, lsdiff)\n" +" -E, --empty-files-as-absent {lsdiff}\n" +" treat empty files as absent {lsdiff}\n" +" --empty-files-as-absent {grepdiff}\n" +" treat empty files as absent {grepdiff}\n" +" -f FILE, --file=FILE {grepdiff}\n" +" read regular expressions from FILE {grepdiff}\n" +" --filter run as 'filterdiff' {grepdiff, patchview, lsdiff}\n" +" --list run as 'lsdiff' {filterdiff, patchview, grepdiff}\n" +" --grep run as 'grepdiff' {filterdiff, patchview, lsdiff}\n" ; NORETURN @@ -1676,8 +1676,8 @@ static void syntax (int err) break; endp = next; *next++ = '\0'; - if (*--endp == ')') { - char *begp = strrchr (p, '('); + if (*--endp == '}') { + char *begp = strrchr (p, '{'); char *comma; if (!begp) break;