Browse Source

format-patch: allow --interdiff to apply to a lone-patch

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>
maint
Eric Sunshine 7 years ago committed by Junio C Hamano
parent
commit
ee6cbf712e
  1. 3
      Documentation/git-format-patch.txt
  2. 8
      builtin/log.c
  3. 14
      log-tree.c
  4. 12
      t/t4014-format-patch.sh

3
Documentation/git-format-patch.txt

@ -230,7 +230,8 @@ feeding the result to `git send-email`. @@ -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

8
builtin/log.c

@ -1540,7 +1540,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) @@ -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) @@ -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) @@ -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;


14
log-tree.c

@ -14,6 +14,7 @@ @@ -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) @@ -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)

12
t/t4014-format-patch.sh

@ -1730,6 +1730,7 @@ test_expect_success 'interdiff: cover-letter' ' @@ -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' ' @@ -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

Loading…
Cancel
Save