|
33 | 33 | #include "repository.h" |
34 | 34 | #include "commit-reach.h" |
35 | 35 | #include "interdiff.h" |
| 36 | +#include "range-diff.h" |
36 | 37 |
|
37 | 38 | #define MAIL_DEFAULT_WRAP 72 |
38 | 39 |
|
@@ -1090,6 +1091,12 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout, |
1090 | 1091 | fprintf_ln(rev->diffopt.file, "%s", rev->idiff_title); |
1091 | 1092 | show_interdiff(rev, 0); |
1092 | 1093 | } |
| 1094 | + |
| 1095 | + if (rev->rdiff1) { |
| 1096 | + fprintf_ln(rev->diffopt.file, "%s", rev->rdiff_title); |
| 1097 | + show_range_diff(rev->rdiff1, rev->rdiff2, |
| 1098 | + rev->creation_factor, 1, &rev->diffopt); |
| 1099 | + } |
1093 | 1100 | } |
1094 | 1101 |
|
1095 | 1102 | static const char *clean_message_id(const char *msg_id) |
@@ -1439,6 +1446,26 @@ static const char *diff_title(struct strbuf *sb, int reroll_count, |
1439 | 1446 | return sb->buf; |
1440 | 1447 | } |
1441 | 1448 |
|
| 1449 | +static void infer_range_diff_ranges(struct strbuf *r1, |
| 1450 | + struct strbuf *r2, |
| 1451 | + const char *prev, |
| 1452 | + struct commit *origin, |
| 1453 | + struct commit *head) |
| 1454 | +{ |
| 1455 | + const char *head_oid = oid_to_hex(&head->object.oid); |
| 1456 | + |
| 1457 | + if (!strstr(prev, "..")) { |
| 1458 | + strbuf_addf(r1, "%s..%s", head_oid, prev); |
| 1459 | + strbuf_addf(r2, "%s..%s", prev, head_oid); |
| 1460 | + } else if (!origin) { |
| 1461 | + die(_("failed to infer range-diff ranges")); |
| 1462 | + } else { |
| 1463 | + strbuf_addstr(r1, prev); |
| 1464 | + strbuf_addf(r2, "%s..%s", |
| 1465 | + oid_to_hex(&origin->object.oid), head_oid); |
| 1466 | + } |
| 1467 | +} |
| 1468 | + |
1442 | 1469 | int cmd_format_patch(int argc, const char **argv, const char *prefix) |
1443 | 1470 | { |
1444 | 1471 | struct commit *commit; |
@@ -1468,6 +1495,11 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) |
1468 | 1495 | struct progress *progress = NULL; |
1469 | 1496 | struct oid_array idiff_prev = OID_ARRAY_INIT; |
1470 | 1497 | struct strbuf idiff_title = STRBUF_INIT; |
| 1498 | + const char *rdiff_prev = NULL; |
| 1499 | + struct strbuf rdiff1 = STRBUF_INIT; |
| 1500 | + struct strbuf rdiff2 = STRBUF_INIT; |
| 1501 | + struct strbuf rdiff_title = STRBUF_INIT; |
| 1502 | + int creation_factor = -1; |
1471 | 1503 |
|
1472 | 1504 | const struct option builtin_format_patch_options[] = { |
1473 | 1505 | { OPTION_CALLBACK, 'n', "numbered", &numbered, NULL, |
@@ -1544,6 +1576,10 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) |
1544 | 1576 | OPT_CALLBACK(0, "interdiff", &idiff_prev, N_("rev"), |
1545 | 1577 | N_("show changes against <rev> in cover letter or single patch"), |
1546 | 1578 | parse_opt_object_name), |
| 1579 | + OPT_STRING(0, "range-diff", &rdiff_prev, N_("refspec"), |
| 1580 | + N_("show changes against <refspec> in cover letter or single patch")), |
| 1581 | + OPT_INTEGER(0, "creation-factor", &creation_factor, |
| 1582 | + N_("percentage by which creation is weighted")), |
1547 | 1583 | OPT_END() |
1548 | 1584 | }; |
1549 | 1585 |
|
@@ -1776,6 +1812,25 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) |
1776 | 1812 | _("Interdiff against v%d:")); |
1777 | 1813 | } |
1778 | 1814 |
|
| 1815 | + if (creation_factor < 0) |
| 1816 | + creation_factor = RANGE_DIFF_CREATION_FACTOR_DEFAULT; |
| 1817 | + else if (!rdiff_prev) |
| 1818 | + die(_("--creation-factor requires --range-diff")); |
| 1819 | + |
| 1820 | + if (rdiff_prev) { |
| 1821 | + if (!cover_letter && total != 1) |
| 1822 | + die(_("--range-diff requires --cover-letter or single patch")); |
| 1823 | + |
| 1824 | + infer_range_diff_ranges(&rdiff1, &rdiff2, rdiff_prev, |
| 1825 | + origin, list[0]); |
| 1826 | + rev.rdiff1 = rdiff1.buf; |
| 1827 | + rev.rdiff2 = rdiff2.buf; |
| 1828 | + rev.creation_factor = creation_factor; |
| 1829 | + rev.rdiff_title = diff_title(&rdiff_title, reroll_count, |
| 1830 | + _("Range-diff:"), |
| 1831 | + _("Range-diff against v%d:")); |
| 1832 | + } |
| 1833 | + |
1779 | 1834 | if (!signature) { |
1780 | 1835 | ; /* --no-signature inhibits all signatures */ |
1781 | 1836 | } else if (signature && signature != git_version_string) { |
@@ -1813,8 +1868,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) |
1813 | 1868 | print_signature(rev.diffopt.file); |
1814 | 1869 | total++; |
1815 | 1870 | start_number--; |
1816 | | - /* interdiff in cover-letter; omit from patches */ |
| 1871 | + /* interdiff/range-diff in cover-letter; omit from patches */ |
1817 | 1872 | rev.idiff_oid1 = NULL; |
| 1873 | + rev.rdiff1 = NULL; |
1818 | 1874 | } |
1819 | 1875 | rev.add_signoff = do_signoff; |
1820 | 1876 |
|
@@ -1899,6 +1955,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) |
1899 | 1955 | done: |
1900 | 1956 | oid_array_clear(&idiff_prev); |
1901 | 1957 | strbuf_release(&idiff_title); |
| 1958 | + strbuf_release(&rdiff1); |
| 1959 | + strbuf_release(&rdiff2); |
| 1960 | + strbuf_release(&rdiff_title); |
1902 | 1961 | return 0; |
1903 | 1962 | } |
1904 | 1963 |
|
|
0 commit comments