format-patch: show base info before email signature

Any text below the "-- " for the email signature gets treated as part of the signature, and many mail clients will trim it from the quoted text for a reply. Move it above the signature, so people can reply to it more easily. Similarly, when producing the patch as a MIME attachment, the original code placed the base info after the attached part, which would be discarded. Move the base info to the end of the part, still inside the part boundary. Add tests for the exact format of the email signature, and add tests to ensure that the base info appears before the email signature when producing a plain-text output, and that it appears before the part boundary when producing a MIME attachment. Signed-off-by: Josh Triplett <josh@joshtriplett.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Josh Triplett committed Sep 7, 2016 at 18:12 UTC 480871e09ed2e5275b4ba16b278681e5a8c122ae
2 files changed +30 -9
builtin/log.c
+3 -3
@@ -1042,7 +1042,6 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
1042 diff_flush(&opts);
1043
1044 fprintf(rev->diffopt.file, "\n");
1045 - print_signature(rev->diffopt.file);
1045 }
1046
1047 static const char *clean_message_id(const char *msg_id)
@@ -1361,7 +1360,7 @@ static void print_bases(struct base_tree_info *bases, FILE *file)
1360 return;
1361
1362 /* Show the base commit */
1364 - fprintf(file, "base-commit: %s\n", oid_to_hex(&bases->base_commit));
1363 + fprintf(file, "\nbase-commit: %s\n", oid_to_hex(&bases->base_commit));
1364
1365 /* Show the prerequisite patches */
1366 for (i = bases->nr_patch_id - 1; i >= 0; i--)
@@ -1720,6 +1719,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1719 make_cover_letter(&rev, use_stdout,
1720 origin, nr, list, branch_name, quiet);
1721 print_bases(&bases, rev.diffopt.file);
1722 + print_signature(rev.diffopt.file);
1723 total++;
1724 start_number--;
1725 }
@@ -1779,13 +1779,13 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1779 if (!use_stdout)
1780 rev.shown_one = 0;
1781 if (shown) {
1782 + print_bases(&bases, rev.diffopt.file);
1783 if (rev.mime_boundary)
1784 fprintf(rev.diffopt.file, "\n--%s%s--\n\n\n",
1785 mime_boundary_leader,
1786 rev.mime_boundary);
1787 else
1788 print_signature(rev.diffopt.file);
1788 - print_bases(&bases, rev.diffopt.file);
1789 }
1790 if (!use_stdout)
1791 fclose(rev.diffopt.file);
t/t4014-format-patch.sh
+27 -6
@@ -754,9 +754,22 @@ test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
754 git format-patch --ignore-if-in-upstream HEAD
755 '
756
757 +git_version="$(git --version | sed "s/.* //")"
758 +
759 +signature() {
760 + printf "%s\n%s\n\n" "-- " "${1:-$git_version}"
761 +}
762 +
763 +test_expect_success 'format-patch default signature' '
764 + git format-patch --stdout -1 | tail -n 3 >output &&
765 + signature >expect &&
766 + test_cmp expect output
767 +'
768 +
769 test_expect_success 'format-patch --signature' '
758 - git format-patch --stdout --signature="my sig" -1 >output &&
759 - grep "my sig" output
770 + git format-patch --stdout --signature="my sig" -1 | tail -n 3 >output &&
771 + signature "my sig" >expect &&
772 + test_cmp expect output
773 '
774
775 test_expect_success 'format-patch with format.signature config' '
@@ -1502,12 +1515,12 @@ test_expect_success 'format-patch -o overrides format.outputDirectory' '
1515
1516 test_expect_success 'format-patch --base' '
1517 git checkout side &&
1505 - git format-patch --stdout --base=HEAD~3 -1 >patch &&
1506 - grep "^base-commit:" patch >actual &&
1507 - grep "^prerequisite-patch-id:" patch >>actual &&
1508 - echo "base-commit: $(git rev-parse HEAD~3)" >expected &&
1518 + git format-patch --stdout --base=HEAD~3 -1 | tail -n 7 >actual &&
1519 + echo >expected &&
1520 + echo "base-commit: $(git rev-parse HEAD~3)" >>expected &&
1521 echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1522 echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1523 + signature >> expected &&
1524 test_cmp expected actual
1525 '
1526
@@ -1605,6 +1618,14 @@ test_expect_success 'format-patch --base overrides format.useAutoBase' '
1618 test_cmp expected actual
1619 '
1620
1621 +test_expect_success 'format-patch --base with --attach' '
1622 + git format-patch --attach=mimemime --stdout --base=HEAD~ -1 >patch &&
1623 + sed -n -e "/^base-commit:/s/.*/1/p" -e "/^---*mimemime--$/s/.*/2/p" \
1624 + patch >actual &&
1625 + test_write_lines 1 2 >expect &&
1626 + test_cmp expect actual
1627 +'
1628 +
1629 test_expect_success 'format-patch --pretty=mboxrd' '
1630 sp=" " &&
1631 cat >msg <<-INPUT_END &&