]> granicus.if.org Git - git/commitdiff
format-patch: allow --interdiff to apply to a lone-patch
authorEric Sunshine <sunshine@sunshineco.com>
Sun, 22 Jul 2018 09:57:09 +0000 (05:57 -0400)
committerJunio C Hamano <gitster@pobox.com>
Mon, 23 Jul 2018 19:50:06 +0000 (12:50 -0700)
When submitting a revised version of a patch or series, it can be
helpful (to reviewers) to include a summary of changes since the
previous attempt in the form of an interdiff, typically in the cover
letter. However, it is occasionally useful, despite making for a noisy
read, to insert an interdiff into the commentary section of the lone
patch of a 1-patch series.

Therefore, extend "git format-patch --interdiff=<prev>" to insert an
interdiff into the commentary section of a lone patch rather than
requiring a cover letter. The interdiff is indented to avoid confusing
git-am and human readers into considering it part of the patch proper.

Implementation note: Generating an interdiff for insertion into the
commentary section of a patch which itself is currently being generated
requires invoking the diffing machinery recursively. However, the
machinery does not (presently) support this since it uses global state.
Consequently, we need to take care to stash away the state of the
in-progress operation while generating the interdiff, and restore it
after.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-format-patch.txt
builtin/log.c
log-tree.c
t/t4014-format-patch.sh

index a1b1bafee708b11da7959646df4462f039a4ec22..f8a061794dcabc1b54a2e17dbfc178b5ce25caf9 100644 (file)
@@ -230,7 +230,8 @@ feeding the result to `git send-email`.
        fill in a description in the file before sending it out.
 
 --interdiff=<previous>::
-       As a reviewer aid, insert an interdiff into the cover letter showing
+       As a reviewer aid, insert an interdiff into the cover letter,
+       or as commentary of the lone patch of a 1-patch series, showing
        the differences between the previous version of the patch series and
        the series currently being formatted. `previous` is a single revision
        naming the tip of the previous series which shares a common base with
index 8078a43d14f014885cc4331cd516efbd5bff6524..e990027c282564e4e60f829a83b546db3604d5e5 100644 (file)
@@ -1540,7 +1540,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                OPT_BOOL(0, "progress", &show_progress,
                         N_("show progress while generating patches")),
                OPT_CALLBACK(0, "interdiff", &idiff_prev, N_("rev"),
-                            N_("show changes against <rev> in cover letter"),
+                            N_("show changes against <rev> in cover letter or single patch"),
                             parse_opt_object_name),
                OPT_END()
        };
@@ -1765,8 +1765,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                rev.total = total + start_number - 1;
 
        if (idiff_prev.nr) {
-               if (!cover_letter)
-                       die(_("--interdiff requires --cover-letter"));
+               if (!cover_letter && total != 1)
+                       die(_("--interdiff requires --cover-letter or single patch"));
                rev.idiff_oid1 = &idiff_prev.oid[idiff_prev.nr - 1];
                rev.idiff_oid2 = get_commit_tree_oid(list[0]);
                rev.idiff_title = diff_title(&idiff_title, reroll_count,
@@ -1811,6 +1811,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                print_signature(rev.diffopt.file);
                total++;
                start_number--;
+               /* interdiff in cover-letter; omit from patches */
+               rev.idiff_oid1 = NULL;
        }
        rev.add_signoff = do_signoff;
 
index 9d38f1cf79c17f5bf651d12b1fe6098233404947..56513fa83ddfaf72a5731ef62600bd32d09977cb 100644 (file)
@@ -14,6 +14,7 @@
 #include "sequencer.h"
 #include "line-log.h"
 #include "help.h"
+#include "interdiff.h"
 
 static struct decoration name_decoration = { "object names" };
 static int decoration_loaded;
@@ -736,6 +737,19 @@ void show_log(struct rev_info *opt)
 
        strbuf_release(&msgbuf);
        free(ctx.notes_message);
+
+       if (cmit_fmt_is_mail(ctx.fmt) && opt->idiff_oid1) {
+               struct diff_queue_struct dq;
+
+               memcpy(&dq, &diff_queued_diff, sizeof(diff_queued_diff));
+               DIFF_QUEUE_CLEAR(&diff_queued_diff);
+
+               next_commentary_block(opt, NULL);
+               fprintf_ln(opt->diffopt.file, "%s", opt->idiff_title);
+               show_interdiff(opt, 2);
+
+               memcpy(&diff_queued_diff, &dq, sizeof(diff_queued_diff));
+       }
 }
 
 int log_tree_diff_flush(struct rev_info *opt)
index 5950890d30c24a3c939e60154df7ae1bff0a50d5..909c743c134c5e18e0a80db3eae2dfb6e8210e6a 100755 (executable)
@@ -1730,6 +1730,7 @@ test_expect_success 'interdiff: cover-letter' '
        EOF
        git format-patch --cover-letter --interdiff=boop~2 -1 boop &&
        test_i18ngrep "^Interdiff:$" 0000-cover-letter.patch &&
+       test_i18ngrep ! "^Interdiff:$" 0001-fleep.patch &&
        sed "1,/^@@ /d; /^-- $/q" <0000-cover-letter.patch >actual &&
        test_cmp expect actual
 '
@@ -1739,4 +1740,15 @@ test_expect_success 'interdiff: reroll-count' '
        test_i18ngrep "^Interdiff ..* v1:$" v2-0000-cover-letter.patch
 '
 
+test_expect_success 'interdiff: solo-patch' '
+       cat >expect <<-\EOF &&
+         +fleep
+
+       EOF
+       git format-patch --interdiff=boop~2 -1 boop &&
+       test_i18ngrep "^Interdiff:$" 0001-fleep.patch &&
+       sed "1,/^  @@ /d; /^$/q" <0001-fleep.patch >actual &&
+       test_cmp expect actual
+'
+
 test_done