From: Junio C Hamano Date: Wed, 18 Jul 2018 19:20:29 +0000 (-0700) Subject: Merge branch 'xy/format-patch-prereq-patch-id-fix' X-Git-Tag: v2.19.0-rc0~161 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/2516b4711f6e180516162c384b7e94832e7189f6?hp=-c Merge branch 'xy/format-patch-prereq-patch-id-fix' Recently added "--base" option to "git format-patch" command did not correctly generate prereq patch ids. * xy/format-patch-prereq-patch-id-fix: format-patch: clear UNINTERESTING flag before prepare_bases --- 2516b4711f6e180516162c384b7e94832e7189f6 diff --combined builtin/log.c index c77af79755,9ee2bd1fd8..805f89d7e1 --- a/builtin/log.c +++ b/builtin/log.c @@@ -7,7 -7,6 +7,7 @@@ #include "cache.h" #include "config.h" #include "refs.h" +#include "object-store.h" #include "color.h" #include "commit.h" #include "diff.h" @@@ -29,9 -28,6 +29,9 @@@ #include "mailmap.h" #include "gpg-interface.h" #include "progress.h" +#include "commit-slab.h" + +#define MAIL_DEFAULT_WRAP 72 /* Set a default date-time format for git log ("log.date" config variable) */ static const char *default_date_mode = NULL; @@@ -150,7 -146,6 +150,7 @@@ static void cmd_log_init_finish(int arg static struct string_list decorate_refs_include = STRING_LIST_INIT_NODUP; struct decoration_filter decoration_filter = {&decorate_refs_include, &decorate_refs_exclude}; + static struct revision_sources revision_sources; const struct option builtin_log_options[] = { OPT__QUIET(&quiet, N_("suppress diff output")), @@@ -193,14 -188,12 +193,14 @@@ if (rev->show_notes) init_display_notes(&rev->notes_opt); - if (rev->diffopt.pickaxe || rev->diffopt.filter || - rev->diffopt.flags.follow_renames) + if ((rev->diffopt.pickaxe_opts & DIFF_PICKAXE_KINDS_MASK) || + rev->diffopt.filter || rev->diffopt.flags.follow_renames) rev->always_show_header = 0; - if (source) - rev->show_source = 1; + if (source) { + init_revision_sources(&revision_sources); + rev->sources = &revision_sources; + } if (mailmap) { rev->mailmap = xcalloc(1, sizeof(struct string_list)); @@@ -523,7 -516,7 +523,7 @@@ static int show_tag_object(const struc { unsigned long size; enum object_type type; - char *buf = read_sha1_file(oid->hash, &type, &size); + char *buf = read_object_file(oid, &type, &size); int offset = 0; if (!buf) @@@ -546,7 -539,7 +546,7 @@@ return 0; } -static int show_tree_object(const unsigned char *sha1, +static int show_tree_object(const struct object_id *oid, struct strbuf *base, const char *pathname, unsigned mode, int stage, void *context) { @@@ -1024,7 -1017,7 +1024,7 @@@ static void make_cover_letter(struct re open_next_file(NULL, rev->numbered_files ? NULL : "cover-letter", rev, quiet)) return; - log_write_email_headers(rev, head, &pp.after_subject, &need_8bit_cte); + log_write_email_headers(rev, head, &pp.after_subject, &need_8bit_cte, 0); for (i = 0; !need_8bit_cte && i < nr; i++) { const char *buf = get_commit_buffer(list[i], NULL); @@@ -1051,7 -1044,7 +1051,7 @@@ shortlog_init(&log); log.wrap_lines = 1; - log.wrap = 72; + log.wrap = MAIL_DEFAULT_WRAP; log.in1 = 2; log.in2 = 4; log.file = rev->diffopt.file; @@@ -1068,12 -1061,11 +1068,12 @@@ memcpy(&opts, &rev->diffopt, sizeof(opts)); opts.output_format = DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT; + opts.stat_width = MAIL_DEFAULT_WRAP; diff_setup_done(&opts); - diff_tree_oid(&origin->tree->object.oid, - &head->tree->object.oid, + diff_tree_oid(get_commit_tree_oid(origin), + get_commit_tree_oid(head), "", &opts); diffcore_std(&opts); diff_flush(&opts); @@@ -1342,8 -1334,6 +1342,8 @@@ static struct commit *get_base_commit(c return base; } +define_commit_slab(commit_base, int); + static void prepare_bases(struct base_tree_info *bases, struct commit *base, struct commit **list, @@@ -1352,13 -1342,11 +1352,13 @@@ struct commit *commit; struct rev_info revs; struct diff_options diffopt; + struct commit_base commit_base; int i; if (!base) return; + init_commit_base(&commit_base); diff_setup(&diffopt); diffopt.flags.recursive = 1; diff_setup_done(&diffopt); @@@ -1371,7 -1359,7 +1371,7 @@@ for (i = 0; i < total; i++) { list[i]->object.flags &= ~UNINTERESTING; add_pending_object(&revs, &list[i]->object, "rev_list"); - list[i]->util = (void *)1; + *commit_base_at(&commit_base, list[i]) = 1; } base->object.flags |= UNINTERESTING; add_pending_object(&revs, &base->object, "base"); @@@ -1385,7 -1373,7 +1385,7 @@@ while ((commit = get_revision(&revs)) != NULL) { struct object_id oid; struct object_id *patch_id; - if (commit->util) + if (*commit_base_at(&commit_base, commit)) continue; if (commit_patch_id(commit, &diffopt, &oid, 0)) die(_("cannot get patch id")); @@@ -1394,7 -1382,6 +1394,7 @@@ oidcpy(patch_id, &oid); bases->nr_patch_id++; } + clear_commit_base(&commit_base); } static void print_bases(struct base_tree_info *bases, FILE *file) @@@ -1484,9 -1471,9 +1484,9 @@@ int cmd_format_patch(int argc, const ch N_("output all-zero hash in From header")), OPT_BOOL(0, "ignore-if-in-upstream", &ignore_if_in_upstream, N_("don't include a patch matching a commit upstream")), - { OPTION_SET_INT, 'p', "no-stat", &use_patch_format, NULL, - N_("show patch format instead of default (patch + stat)"), - PARSE_OPT_NONEG | PARSE_OPT_NOARG, NULL, 1}, + OPT_SET_INT_F('p', "no-stat", &use_patch_format, + N_("show patch format instead of default (patch + stat)"), + 1, PARSE_OPT_NONEG), OPT_GROUP(N_("Messaging")), { OPTION_CALLBACK, 0, "add-header", NULL, N_("header"), N_("add email header"), 0, header_callback }, @@@ -1627,8 -1614,6 +1627,8 @@@ (!rev.diffopt.output_format || rev.diffopt.output_format == DIFF_FORMAT_PATCH)) rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY; + if (!rev.diffopt.stat_width) + rev.diffopt.stat_width = MAIL_DEFAULT_WRAP; /* Always generate a patch */ rev.diffopt.output_format |= DIFF_FORMAT_PATCH; @@@ -1756,6 -1741,7 +1756,7 @@@ if (base_commit || base_auto) { struct commit *base = get_base_commit(base_commit, list, nr); reset_revision_walk(); + clear_object_flags(UNINTERESTING); prepare_bases(&bases, base, list, nr); } @@@ -1883,12 -1869,12 +1884,12 @@@ static void print_commit(char sign, str { if (!verbose) { fprintf(file, "%c %s\n", sign, - find_unique_abbrev(commit->object.oid.hash, abbrev)); + find_unique_abbrev(&commit->object.oid, abbrev)); } else { struct strbuf buf = STRBUF_INIT; pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf); fprintf(file, "%c %s %s\n", sign, - find_unique_abbrev(commit->object.oid.hash, abbrev), + find_unique_abbrev(&commit->object.oid, abbrev), buf.buf); strbuf_release(&buf); } diff --combined t/t4014-format-patch.sh index 028d5507a6,b67d5729df..53880da7bb --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@@ -578,11 -578,7 +578,11 @@@ test_expect_success 'excessive subject rm -rf patches/ && git checkout side && + before=$(git hash-object file) && + before=$(git rev-parse --short $before) && for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file && + after=$(git hash-object file) && + after=$(git rev-parse --short $after) && git update-index file && git commit -m "This is an excessively long subject line for a message due to the habit some projects have of not having a short, one-line subject at the start of the commit message, but rather sticking a whole paragraph right at the start as the only thing in the commit message. It had better not become the filename for the patch." && git format-patch -o patches/ master..side && @@@ -590,6 -586,7 +590,6 @@@ ' test_expect_success 'cover-letter inherits diff options' ' - git mv file foo && git commit -m foo && git format-patch --no-renames --cover-letter -1 && @@@ -619,7 -616,7 +619,7 @@@ test_expect_success 'shortlog of cover- ' cat > expect << EOF -index 40f36c6..2dc5c23 100644 +index $before..$after 100644 --- a/file +++ b/file @@ -13,4 +13,20 @@ C @@@ -643,7 -640,7 +643,7 @@@ test_expect_success 'format-patch respe cat > expect << EOF diff --git a/file b/file -index 40f36c6..2dc5c23 100644 +index $before..$after 100644 --- a/file +++ b/file @@ -14,3 +14,19 @@ C @@@ -1526,14 -1523,14 +1526,14 @@@ test_expect_success 'cover letter auto test_expect_success 'format-patch --zero-commit' ' git format-patch --zero-commit --stdout v2..v1 >patch2 && grep "^From " patch2 | sort | uniq >actual && - echo "From $_z40 Mon Sep 17 00:00:00 2001" >expect && + echo "From $ZERO_OID Mon Sep 17 00:00:00 2001" >expect && test_cmp expect actual ' test_expect_success 'From line has expected format' ' git format-patch --stdout v2..v1 >patch2 && grep "^From " patch2 >from && - grep "^From $_x40 Mon Sep 17 00:00:00 2001$" patch2 >filtered && + grep "^From $OID_REGEX Mon Sep 17 00:00:00 2001$" patch2 >filtered && test_cmp from filtered ' @@@ -1554,13 -1551,15 +1554,15 @@@ test_expect_success 'format-patch -o ov test_expect_success 'format-patch --base' ' git checkout side && - git format-patch --stdout --base=HEAD~3 -1 | tail -n 7 >actual && + git format-patch --stdout --base=HEAD~3 -1 | tail -n 7 >actual1 && + git format-patch --stdout --base=HEAD~3 HEAD~.. | tail -n 7 >actual2 && echo >expected && echo "base-commit: $(git rev-parse HEAD~3)" >>expected && echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --stable | awk "{print \$1}")" >>expected && echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected && signature >> expected && - test_cmp expected actual + test_cmp expected actual1 && + test_cmp expected actual2 ' test_expect_success 'format-patch --base errors out when base commit is in revision list' ' @@@ -1664,15 -1663,6 +1666,15 @@@ test_expect_success 'format-patch --bas test_write_lines 1 2 >expect && test_cmp expect actual ' +test_expect_success 'format-patch --attach cover-letter only is non-multipart' ' + test_when_finished "rm -fr patches" && + git format-patch -o patches --cover-letter --attach=mimemime --base=HEAD~ -1 && + ! egrep "^--+mimemime" patches/0000*.patch && + egrep "^--+mimemime$" patches/0001*.patch >output && + test_line_count = 2 output && + egrep "^--+mimemime--$" patches/0001*.patch >output && + test_line_count = 1 output +' test_expect_success 'format-patch --pretty=mboxrd' ' sp=" " &&