The diffs queued from git-diff-pairs(1) are flushed when stdin is closed. To enable greater flexibility, allow control over when the diff queue is flushed by writing a single NUL byte on stdin between input file pairs. Diff output between flushes is separated by a single NUL byte. Signed-off-by: Justin Tobler <jltobler@xxxxxxxxx> --- Documentation/git-diff-pairs.adoc | 4 ++++ builtin/diff-pairs.c | 13 +++++++++++++ t/t4070-diff-pairs.sh | 9 +++++++++ 3 files changed, 26 insertions(+) diff --git a/Documentation/git-diff-pairs.adoc b/Documentation/git-diff-pairs.adoc index e31f2e2fbb..f99fcd1ead 100644 --- a/Documentation/git-diff-pairs.adoc +++ b/Documentation/git-diff-pairs.adoc @@ -17,6 +17,10 @@ in the NUL-terminated raw output format as generated by commands such as `git diff-tree -z -r --raw`. By default, the outputted diffs are computed and shown in the patch format when stdin closes. +A single NUL byte may be written to stdin between raw input lines to compute +file pair diffs up to that point instead of waiting for stdin to close. A NUL +byte is also written to the output to delimit between these batches of diffs. + Usage of this command enables the traditional diff pipeline to be broken up into separate stages where `diff-pairs` acts as the output phase. Other commands, such as `diff-tree`, may serve as a frontend to compute the raw diff --git a/builtin/diff-pairs.c b/builtin/diff-pairs.c index 9472b10461..7130569332 100644 --- a/builtin/diff-pairs.c +++ b/builtin/diff-pairs.c @@ -63,6 +63,7 @@ int cmd_diff_pairs(int argc, const char **argv, const char *prefix, repo_init_revisions(repo, &revs, prefix); repo_config(repo, git_diff_basic_config, NULL); + revs.diffopt.no_free = 1; revs.disable_stdin = 1; revs.abbrev = 0; revs.diff = 1; @@ -106,6 +107,17 @@ int cmd_diff_pairs(int argc, const char **argv, const char *prefix, break; p = meta.buf; + if (!*p) { + flush_diff_queue(&revs.diffopt); + /* + * When the diff queue is explicitly flushed, append a + * NUL byte to separate batches of diffs. + */ + fputc('\0', revs.diffopt.file); + fflush(revs.diffopt.file); + continue; + } + if (*p != ':') die(_("invalid raw diff input")); p++; @@ -180,6 +192,7 @@ int cmd_diff_pairs(int argc, const char **argv, const char *prefix, } } + revs.diffopt.no_free = 0; flush_diff_queue(&revs.diffopt); ret = diff_result_code(&revs); diff --git a/t/t4070-diff-pairs.sh b/t/t4070-diff-pairs.sh index 2f511cc9c9..3352bfe0b9 100755 --- a/t/t4070-diff-pairs.sh +++ b/t/t4070-diff-pairs.sh @@ -71,4 +71,13 @@ test_expect_success 'diff-pairs does not support pathspec arguments' ' grep "error: pathspec arguments not supported" err ' +test_expect_success 'diff-pairs explicit queue flush' ' + git diff-tree -r -M -C -C -z base new >expect && + printf "\0" >>expect && + git diff-tree -r -M -C -C -z base new >>expect && + + git diff-pairs --raw -z <expect >actual && + test_cmp expect actual +' + test_done -- 2.48.1