]> git.ipfire.org Git - thirdparty/git.git/commitdiff
builtin/diff-pairs: allow explicit diff queue flush
authorJustin Tobler <jltobler@gmail.com>
Fri, 28 Feb 2025 21:33:46 +0000 (15:33 -0600)
committerJunio C Hamano <gitster@pobox.com>
Mon, 3 Mar 2025 16:17:47 +0000 (08:17 -0800)
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@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-diff-pairs.adoc
builtin/diff-pairs.c
t/t4070-diff-pairs.sh

index e31f2e2fbbc5270c6352690c6ce254d6cf420d36..f99fcd1ead2479b3dfef739426519dee2bf75e49 100644 (file)
@@ -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
index 6be17c1abd4ea02097510e34e55ba18587000838..71c045331ab729b19f36fa7f8c35d0af81144fad 100644 (file)
@@ -57,6 +57,7 @@ int cmd_diff_pairs(int argc, const char **argv, const char *prefix,
        show_usage_with_options_if_asked(argc, argv, builtin_diff_pairs_usage, parseopts);
 
        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,18 @@ int cmd_diff_pairs(int argc, const char **argv, const char *prefix,
                        break;
 
                p = meta.buf;
+               if (!*p) {
+                       diffcore_std(&revs.diffopt);
+                       diff_flush(&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++;
@@ -179,6 +192,7 @@ int cmd_diff_pairs(int argc, const char **argv, const char *prefix,
                }
        }
 
+       revs.diffopt.no_free = 0;
        diffcore_std(&revs.diffopt);
        diff_flush(&revs.diffopt);
        ret = diff_result_code(&revs);
index 0878ad0ad168cd1e93d3bc10b8827cab836ecdc9..70deafb860e57f484daa4a4fbe882f4b283dde49 100755 (executable)
@@ -78,4 +78,13 @@ test_expect_success 'diff-pairs does not support pathspec arguments' '
        test_cmp expect 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