Files
git/diff-process.h
Michael Montalbo dcb7920f8c diff: add long-running diff process via diff.<driver>.process
Add support for external diff processes that communicate via the
long-running process protocol (pkt-line over stdin/stdout).

A diff process is configured per userdiff driver:

    [diff "cdiff"]
        process = /path/to/diff-tool

The tool provides custom line-matching: it receives file pairs
and returns hunks that reference line numbers in the content.
When textconv is also configured, the tool receives the
textconv-transformed content.  The tool controls which lines
are marked as changed while the display shows the file content.
Patch output features (word diff, function context, color) work
normally; summary formats like --stat use their own diff path
and are not affected.

The handshake negotiates version=1 and capability=hunks.  Per-file
requests send command=hunks, pathname, and both file contents as
packetized data.  The tool responds with hunk lines and a status
packet (success, error, or abort).  On error, Git warns and falls
back to the builtin diff algorithm for that file.  On abort, Git
silently falls back for the current file and stops sending further
requests to the tool for the remainder of the session.

When the tool returns no hunks followed by status=success, Git
treats the file as having no changes and produces no diff output.
This also means --exit-code reports no changes for that file.

The subprocess is stored on the userdiff_driver struct and
launched on first use.  If the process fails to start, the
handshake fails, or a communication error occurs mid-stream,
the failure is cached on the driver to avoid retrying and
re-warning on every subsequent file.

diff_process_fill_hunks() is the sole public entry point.  It
handles driver lookup, flag checks, subprocess management, and
error reporting, returning an enum that lets callers distinguish
"hunks populated" from "files equivalent" from "not applicable"
from "tool failure."

Signed-off-by: Michael Montalbo <mmontalbo@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-30 08:14:32 +09:00

40 lines
1.3 KiB
C

#ifndef DIFF_PROCESS_H
#define DIFF_PROCESS_H
#include "xdiff/xdiff.h"
struct diff_options;
enum diff_process_result {
DIFF_PROCESS_ERROR = -1, /* tool failure: warned, fell back */
DIFF_PROCESS_OK = 0, /* hunks populated in xpp */
DIFF_PROCESS_SKIP, /* no process configured: use builtin */
DIFF_PROCESS_EQUIVALENT, /* tool says files are equivalent */
};
/*
* Consult the diff process configured for 'path' and populate
* xpp->external_hunks with the returned hunks.
*
* Handles driver lookup, flag checks (--no-ext-diff,
* --diff-algorithm), subprocess management, and error reporting.
*
* Returns DIFF_PROCESS_OK when hunks are populated in xpp.
* The caller owns xpp->external_hunks and must free() it.
*
* Returns DIFF_PROCESS_EQUIVALENT when the tool returns no hunks
* (files are considered identical); caller should skip diff/blame.
* Returns DIFF_PROCESS_SKIP when no process applies; caller
* should use the builtin diff algorithm.
* Returns DIFF_PROCESS_ERROR on tool failure (already warned);
* caller should fall back to the builtin diff algorithm.
*/
enum diff_process_result diff_process_fill_hunks(
struct diff_options *diffopt,
const char *path,
const mmfile_t *file_a,
const mmfile_t *file_b,
xpparam_t *xpp);
#endif /* DIFF_PROCESS_H */