Skip to content

Non-interactive --color-only filter mode for interactive.diffFilter (git add -p) #575

Description

@HadrienPatte

What do you want to change?

Add a non-interactive filter mode, e.g. a --color-only / --filter flag, or a dedicated hunk filter subcommand that reads a unified diff from stdin, applies Hunk's syntax highlighting and diff coloring, writes the result to stdout as an ANSI-colored diff, and exits with no interactive UI or TTY dependency.

Intended use:

gitconfig
[interactive]
    diffFilter = hunk <the-new-flag-or-subcommand>

Why?

Hunk works well as core.pager, but there's one place in the standard Git workflow it can't reach today: git add -p (and git stash -p, git reset -p, etc.). These interactive-staging commands don't send hunks to the pager, they read them back through interactive.diffFilter, which has a fundamentally different contract:

  • A pager owns the terminal (a TTY), renders a full-screen UI, and waits for user navigation.
  • A diffFilter is a non-interactive text transform: Git pipes one hunk's diff to the filter's stdin, expects colorized diff text back on stdout, and re-parses that output to drive its own y/n/s/q prompts. stdout is a pipe, not a TTY, and the filter must not read stdin interactively or hold the terminal.

Because every Hunk command is an interactive viewer, there's currently no way to wire Hunk into interactive.diffFilter. Doing so causes git add -p to hang, since Hunk grabs the terminal and blocks on input Git needs for its own prompts. This is the gap delta closes with delta --color-only. Users attempting to migrate from delta to hunk must keep delta for their diffFilter.

How? (optional)

This shares machinery with #247 (streaming pager mode). Both require a non-interactive, stdout-oriented render path rather than the interactive TUI. The bounded patch sniffer and per-file chunker proposed there are exactly the pieces a filter mode would render from. A --color-only filter is essentially "the streaming render path, minus the pager UI, one hunk at a time, straight to stdout." If #247 lands its incremental parse/render pipeline, exposing a filter entry point on top of it should be a small addition rather than a parallel implementation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions