From: Junio C Hamano Date: Thu, 28 Apr 2011 21:11:43 +0000 (-0700) Subject: Merge branch 'jc/rename-degrade-cc-to-c' X-Git-Tag: v1.7.6-rc0~135 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/76a89d6d828486f96f42c69ef0cf87bb6b72fef5?ds=inline;hp=-c Merge branch 'jc/rename-degrade-cc-to-c' * jc/rename-degrade-cc-to-c: diffcore-rename: fall back to -C when -C -C busts the rename limit diffcore-rename: record filepair for rename src diffcore-rename: refactor "too many candidates" logic builtin/diff.c: remove duplicated call to diff_result_code() --- 76a89d6d828486f96f42c69ef0cf87bb6b72fef5 diff --combined builtin/diff.c index 717fa1a341,171ac39274..14bd14fce0 --- a/builtin/diff.c +++ b/builtin/diff.c @@@ -71,9 -71,9 +71,9 @@@ static int builtin_diff_b_f(struct rev_ usage(builtin_diff_usage); if (lstat(path, &st)) - die_errno("failed to stat '%s'", path); + die_errno(_("failed to stat '%s'"), path); if (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode))) - die("'%s': not a regular file or symlink", path); + die(_("'%s': not a regular file or symlink"), path); diff_set_mnemonic_prefix(&revs->diffopt, "o/", "w/"); @@@ -197,12 -197,16 +197,11 @@@ static void refresh_index_quietly(void discard_cache(); read_cache(); refresh_cache(REFRESH_QUIET|REFRESH_UNMERGED); - - if (active_cache_changed && - !write_cache(fd, active_cache, active_nr)) - commit_locked_index(lock_file); - - rollback_lock_file(lock_file); + update_index_if_able(&the_index, lock_file); } static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv) { - int result; unsigned int options = 0; while (1 < argc && argv[1][0] == '-') { @@@ -217,7 -221,7 +216,7 @@@ else if (!strcmp(argv[1], "-h")) usage(builtin_diff_usage); else - return error("invalid option: %s", argv[1]); + return error(_("invalid option: %s"), argv[1]); argv++; argc--; } @@@ -236,8 -240,7 +235,7 @@@ perror("read_cache_preload"); return -1; } - result = run_diff_files(revs, options); - return diff_result_code(&revs->diffopt, result); + return run_diff_files(revs, options); } int cmd_diff(int argc, const char **argv, const char *prefix) @@@ -294,12 -297,12 +292,12 @@@ DIFF_OPT_SET(&rev.diffopt, ALLOW_TEXTCONV); if (nongit) - die("Not a git repository"); + die(_("Not a git repository")); argc = setup_revisions(argc, argv, &rev, NULL); if (!rev.diffopt.output_format) { rev.diffopt.output_format = DIFF_FORMAT_PATCH; if (diff_setup_done(&rev.diffopt) < 0) - die("diff_setup_done failed"); + die(_("diff_setup_done failed")); } DIFF_OPT_SET(&rev.diffopt, RECURSIVE); @@@ -344,12 -347,12 +342,12 @@@ obj = parse_object(obj->sha1); obj = deref_tag(obj, NULL, 0); if (!obj) - die("invalid object '%s' given.", name); + die(_("invalid object '%s' given."), name); if (obj->type == OBJ_COMMIT) obj = &((struct commit *)obj)->tree->object; if (obj->type == OBJ_TREE) { if (ARRAY_SIZE(ent) <= ents) - die("more than %d trees given: '%s'", + die(_("more than %d trees given: '%s'"), (int) ARRAY_SIZE(ent), name); obj->flags |= flags; ent[ents].item = obj; @@@ -359,7 -362,7 +357,7 @@@ } if (obj->type == OBJ_BLOB) { if (2 <= blobs) - die("more than two blobs given: '%s'", name); + die(_("more than two blobs given: '%s'"), name); hashcpy(blob[blobs].sha1, obj->sha1); blob[blobs].name = name; blob[blobs].mode = list->mode; @@@ -367,7 -370,7 +365,7 @@@ continue; } - die("unhandled object '%s' given.", name); + die(_("unhandled object '%s' given."), name); } if (rev.prune_data.nr) { if (!path) diff --combined builtin/log.c index c6dce9b895,707fd5706c..55abe07610 --- a/builtin/log.c +++ b/builtin/log.c @@@ -49,8 -49,13 +49,8 @@@ static int parse_decoration_style(cons return -1; } -static void cmd_log_init(int argc, const char **argv, const char *prefix, - struct rev_info *rev, struct setup_revision_opt *opt) +static void cmd_log_init_defaults(struct rev_info *rev) { - int i; - int decoration_given = 0; - struct userformat_want w; - rev->abbrev = DEFAULT_ABBREV; rev->commit_format = CMIT_FMT_DEFAULT; if (fmt_pretty) @@@ -63,14 -68,7 +63,14 @@@ if (default_date_mode) rev->date_mode = parse_date_format(default_date_mode); +} +static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, + struct rev_info *rev, struct setup_revision_opt *opt) +{ + int i; + int decoration_given = 0; + struct userformat_want w; /* * Check for -h before setup_revisions(), or "git log -h" will * fail when run without a git directory. @@@ -103,7 -101,7 +103,7 @@@ const char *v = skip_prefix(arg, "--decorate="); decoration_style = parse_decoration_style(arg, v); if (decoration_style < 0) - die("invalid --decorate option: %s", arg); + die(_("invalid --decorate option: %s"), arg); decoration_given = 1; } else if (!strcmp(arg, "--no-decorate")) { decoration_style = 0; @@@ -112,7 -110,7 +112,7 @@@ } else if (!strcmp(arg, "-h")) { usage(builtin_log_usage); } else - die("unrecognized argument: %s", arg); + die(_("unrecognized argument: %s"), arg); } /* @@@ -130,13 -128,6 +130,13 @@@ setup_pager(); } +static void cmd_log_init(int argc, const char **argv, const char *prefix, + struct rev_info *rev, struct setup_revision_opt *opt) +{ + cmd_log_init_defaults(rev); + cmd_log_init_finish(argc, argv, prefix, rev, opt); +} + /* * This gives a rough estimate for how many commits we * will print out in the list. @@@ -162,7 -153,7 +162,7 @@@ static void show_early_header(struct re if (rev->commit_format != CMIT_FMT_ONELINE) putchar(rev->diffopt.line_termination); } - printf("Final output: %d %s\n", nr, stage); + printf(_("Final output: %d %s\n"), nr, stage); } static struct itimerval early_output_timer; @@@ -256,12 -247,14 +256,14 @@@ static void finish_early_output(struct static int cmd_log_walk(struct rev_info *rev) { struct commit *commit; + int saved_nrl = 0; + int saved_dcctc = 0; if (rev->early_output) setup_early_output(rev); if (prepare_revision_walk(rev)) - die("revision walk setup failed"); + die(_("revision walk setup failed")); if (rev->early_output) finish_early_output(rev); @@@ -286,7 -279,14 +288,14 @@@ } free_commit_list(commit->parents); commit->parents = NULL; + if (saved_nrl < rev->diffopt.needed_rename_limit) + saved_nrl = rev->diffopt.needed_rename_limit; + if (rev->diffopt.degraded_cc_to_c) + saved_dcctc = 1; } + rev->diffopt.degraded_cc_to_c = saved_dcctc; + rev->diffopt.needed_rename_limit = saved_nrl; + if (rev->diffopt.output_format & DIFF_FORMAT_CHECKDIFF && DIFF_OPT_TST(&rev->diffopt, CHECK_FAILED)) { return 02; @@@ -358,7 -358,7 +367,7 @@@ static int show_object(const unsigned c int offset = 0; if (!buf) - return error("Could not read object %s", sha1_to_hex(sha1)); + return error(_("Could not read object %s"), sha1_to_hex(sha1)); if (show_tag_object) while (offset < size && buf[offset] != '\n') { @@@ -445,7 -445,7 +454,7 @@@ int cmd_show(int argc, const char **arg break; o = parse_object(t->tagged->sha1); if (!o) - ret = error("Could not read object %s", + ret = error(_("Could not read object %s"), sha1_to_hex(t->tagged->sha1)); objects[i].item = o; i--; @@@ -469,7 -469,7 +478,7 @@@ ret = cmd_log_walk(&rev); break; default: - ret = error("Unknown type: %d", o->type); + ret = error(_("Unknown type: %d"), o->type); } } free(objects); @@@ -495,11 -495,16 +504,11 @@@ int cmd_log_reflog(int argc, const cha rev.verbose_header = 1; memset(&opt, 0, sizeof(opt)); opt.def = "HEAD"; - cmd_log_init(argc, argv, prefix, &rev, &opt); - - /* - * This means that we override whatever commit format the user gave - * on the cmd line. Sad, but cmd_log_init() currently doesn't - * allow us to set a different default. - */ + cmd_log_init_defaults(&rev); rev.commit_format = CMIT_FMT_ONELINE; rev.use_terminator = 1; rev.always_show_header = 1; + cmd_log_init_finish(argc, argv, prefix, &rev, &opt); return cmd_log_walk(&rev); } @@@ -564,7 -569,7 +573,7 @@@ static int git_format_config(const cha { if (!strcmp(var, "format.headers")) { if (!value) - die("format.headers without value"); + die(_("format.headers without value")); add_header(value); return 0; } @@@ -627,7 -632,7 +636,7 @@@ static FILE *realstdout = NULL static const char *output_directory = NULL; static int outdir_offset; -static int reopen_stdout(struct commit *commit, struct rev_info *rev) +static int reopen_stdout(struct commit *commit, struct rev_info *rev, int quiet) { struct strbuf filename = STRBUF_INIT; int suffix_len = strlen(fmt_patch_suffix) + 1; @@@ -636,18 -641,18 +645,18 @@@ strbuf_addstr(&filename, output_directory); if (filename.len >= PATH_MAX - FORMAT_PATCH_NAME_MAX - suffix_len) - return error("name of output directory is too long"); + return error(_("name of output directory is too long")); if (filename.buf[filename.len - 1] != '/') strbuf_addch(&filename, '/'); } get_patch_filename(commit, rev->nr, fmt_patch_suffix, &filename); - if (!DIFF_OPT_TST(&rev->diffopt, QUICK)) + if (!quiet) fprintf(realstdout, "%s\n", filename.buf + outdir_offset); if (freopen(filename.buf, "w", stdout) == NULL) - return error("Cannot open patch file %s", filename.buf); + return error(_("Cannot open patch file %s"), filename.buf); strbuf_release(&filename); return 0; @@@ -661,7 -666,7 +670,7 @@@ static void get_patch_ids(struct rev_in unsigned flags1, flags2; if (rev->pending.nr != 2) - die("Need exactly one range."); + die(_("Need exactly one range.")); o1 = rev->pending.objects[0].item; flags1 = o1->flags; @@@ -669,7 -674,7 +678,7 @@@ flags2 = o2->flags; if ((flags1 & UNINTERESTING) == (flags2 & UNINTERESTING)) - die("Not a range."); + die(_("Not a range.")); init_patch_ids(ids); @@@ -680,7 -685,7 +689,7 @@@ add_pending_object(&check_rev, o1, "o1"); add_pending_object(&check_rev, o2, "o2"); if (prepare_revision_walk(&check_rev)) - die("revision walk setup failed"); + die(_("revision walk setup failed")); while ((commit = get_revision(&check_rev)) != NULL) { /* ignore merges */ @@@ -706,7 -711,7 +715,7 @@@ static void gen_message_id(struct rev_i const char *email_end = strrchr(committer, '>'); struct strbuf buf = STRBUF_INIT; if (!email_start || !email_end || email_start > email_end - 1) - die("Could not extract email from committer identity."); + die(_("Could not extract email from committer identity.")); strbuf_addf(&buf, "%s.%lu.git.%.*s", base, (unsigned long) time(NULL), (int)(email_end - email_start - 1), email_start + 1); @@@ -722,8 -727,7 +731,8 @@@ static void print_signature(void static void make_cover_letter(struct rev_info *rev, int use_stdout, int numbered, int numbered_files, struct commit *origin, - int nr, struct commit **list, struct commit *head) + int nr, struct commit **list, struct commit *head, + int quiet) { const char *committer; const char *subject_start = NULL; @@@ -739,7 -743,7 +748,7 @@@ struct commit *commit = NULL; if (rev->commit_format != CMIT_FMT_EMAIL) - die("Cover letter needs email format"); + die(_("Cover letter needs email format")); committer = git_committer_info(0); @@@ -759,7 -763,7 +768,7 @@@ sha1_to_hex(head->object.sha1), committer, committer); } - if (!use_stdout && reopen_stdout(commit, rev)) + if (!use_stdout && reopen_stdout(commit, rev, quiet)) return; if (commit) { @@@ -832,7 -836,7 +841,7 @@@ static const char *clean_message_id(con m++; } if (!z) - die("insane in-reply-to: %s", msg_id); + die(_("insane in-reply-to: %s"), msg_id); if (++z == m) return a; return xmemdupz(a, z - a); @@@ -905,7 -909,7 +914,7 @@@ static int output_directory_callback(co { const char **dir = (const char **)opt->value; if (*dir) - die("Two output directories?"); + die(_("Two output directories?")); *dir = arg; return 0; } @@@ -1000,7 -1004,6 +1009,7 @@@ int cmd_format_patch(int argc, const ch char *add_signoff = NULL; struct strbuf buf = STRBUF_INIT; int use_patch_format = 0; + int quiet = 0; const struct option builtin_format_patch_options[] = { { OPTION_CALLBACK, 'n', "numbered", &numbered, NULL, "use [PATCH n/m] even with a single patch", @@@ -1056,8 -1059,6 +1065,8 @@@ PARSE_OPT_OPTARG, thread_callback }, OPT_STRING(0, "signature", &signature, "signature", "add a signature"), + OPT_BOOLEAN(0, "quiet", &quiet, + "don't print the patch filenames"), OPT_END() }; @@@ -1069,7 -1070,7 +1078,7 @@@ rev.commit_format = CMIT_FMT_EMAIL; rev.verbose_header = 1; rev.diff = 1; - rev.no_merges = 1; + rev.max_parents = 1; DIFF_OPT_SET(&rev.diffopt, RECURSIVE); rev.subject_prefix = fmt_patch_subject_prefix; memset(&s_r_opt, 0, sizeof(s_r_opt)); @@@ -1096,7 -1097,7 +1105,7 @@@ committer = git_committer_info(IDENT_ERROR_ON_NO_NAME); endpos = strchr(committer, '>'); if (!endpos) - die("bogus committer info %s", committer); + die(_("bogus committer info %s"), committer); add_signoff = xmemdupz(committer, endpos - committer + 1); } @@@ -1141,20 -1142,20 +1150,20 @@@ numbered = 0; if (numbered && keep_subject) - die ("-n and -k are mutually exclusive."); + die (_("-n and -k are mutually exclusive.")); if (keep_subject && subject_prefix) - die ("--subject-prefix and -k are mutually exclusive."); + die (_("--subject-prefix and -k are mutually exclusive.")); argc = setup_revisions(argc, argv, &rev, &s_r_opt); if (argc > 1) - die ("unrecognized argument: %s", argv[1]); + die (_("unrecognized argument: %s"), argv[1]); if (rev.diffopt.output_format & DIFF_FORMAT_NAME) - die("--name-only does not make sense"); + die(_("--name-only does not make sense")); if (rev.diffopt.output_format & DIFF_FORMAT_NAME_STATUS) - die("--name-status does not make sense"); + die(_("--name-status does not make sense")); if (rev.diffopt.output_format & DIFF_FORMAT_CHECKDIFF) - die("--check does not make sense"); + die(_("--check does not make sense")); if (!use_patch_format && (!rev.diffopt.output_format || @@@ -1177,9 -1178,9 +1186,9 @@@ if (output_directory) { if (use_stdout) - die("standard output, or directory, which one?"); + die(_("standard output, or directory, which one?")); if (mkdir(output_directory, 0777) < 0 && errno != EEXIST) - die_errno("Could not create directory '%s'", + die_errno(_("Could not create directory '%s'"), output_directory); } @@@ -1233,7 -1234,7 +1242,7 @@@ realstdout = xfdopen(xdup(1), "w"); if (prepare_revision_walk(&rev)) - die("revision walk setup failed"); + die(_("revision walk setup failed")); rev.boundary = 1; while ((commit = get_revision(&rev)) != NULL) { if (commit->object.flags & BOUNDARY) { @@@ -1267,7 -1268,7 +1276,7 @@@ if (thread) gen_message_id(&rev, "cover"); make_cover_letter(&rev, use_stdout, numbered, numbered_files, - origin, nr, list, head); + origin, nr, list, head, quiet); total++; start_number--; } @@@ -1313,8 -1314,8 +1322,8 @@@ } if (!use_stdout && reopen_stdout(numbered_files ? NULL : commit, - &rev)) - die("Failed to create output files"); + &rev, quiet)) + die(_("Failed to create output files")); shown = log_tree_commit(&rev, commit); free(commit->buffer); commit->buffer = NULL; @@@ -1418,9 -1419,9 +1427,9 @@@ int cmd_cherry(int argc, const char **a if (!current_branch || !current_branch->merge || !current_branch->merge[0] || !current_branch->merge[0]->dst) { - fprintf(stderr, "Could not find a tracked" + fprintf(stderr, _("Could not find a tracked" " remote branch, please" - " specify manually.\n"); + " specify manually.\n")); usage_with_options(cherry_usage, options); } @@@ -1434,9 -1435,9 +1443,9 @@@ DIFF_OPT_SET(&revs.diffopt, RECURSIVE); if (add_pending_commit(head, &revs, 0)) - die("Unknown commit %s", head); + die(_("Unknown commit %s"), head); if (add_pending_commit(upstream, &revs, UNINTERESTING)) - die("Unknown commit %s", upstream); + die(_("Unknown commit %s"), upstream); /* Don't say anything if head and upstream are the same. */ if (revs.pending.nr == 2) { @@@ -1448,11 -1449,11 +1457,11 @@@ get_patch_ids(&revs, &ids, prefix); if (limit && add_pending_commit(limit, &revs, UNINTERESTING)) - die("Unknown commit %s", limit); + die(_("Unknown commit %s"), limit); /* reverse the list of commits */ if (prepare_revision_walk(&revs)) - die("revision walk setup failed"); + die(_("revision walk setup failed")); while ((commit = get_revision(&revs)) != NULL) { /* ignore merges */ if (commit->parents && commit->parents->next) diff --combined diff.c index 5376d01e1b,13f322bc5f..56758c7dca --- a/diff.c +++ b/diff.c @@@ -1242,7 -1242,7 +1242,7 @@@ static void show_stats(struct diffstat_ uintmax_t max_change = 0, max_len = 0; int total_files = data->nr; int width, name_width; - const char *reset, *set, *add_c, *del_c; + const char *reset, *add_c, *del_c; const char *line_prefix = ""; struct strbuf *msg = NULL; @@@ -1269,6 -1269,7 +1269,6 @@@ /* Find the longest filename and max number of changes */ reset = diff_get_color_opt(options, DIFF_RESET); - set = diff_get_color_opt(options, DIFF_PLAIN); add_c = diff_get_color_opt(options, DIFF_FILE_NEW); del_c = diff_get_color_opt(options, DIFF_FILE_OLD); @@@ -1538,36 -1539,8 +1538,36 @@@ static void show_dirstat(struct diff_op struct diff_filepair *p = q->queue[i]; const char *name; unsigned long copied, added, damage; + int content_changed; - name = p->one->path ? p->one->path : p->two->path; + name = p->two->path ? p->two->path : p->one->path; + + if (p->one->sha1_valid && p->two->sha1_valid) + content_changed = hashcmp(p->one->sha1, p->two->sha1); + else + content_changed = 1; + + if (!content_changed) { + /* + * The SHA1 has not changed, so pre-/post-content is + * identical. We can therefore skip looking at the + * file contents altogether. + */ + damage = 0; + goto found_damage; + } + + if (DIFF_OPT_TST(options, DIRSTAT_BY_FILE)) { + /* + * In --dirstat-by-file mode, we don't really need to + * look at the actual file contents at all. + * The fact that the SHA1 changed is enough for us to + * add this file to the list of results + * (with each file contributing equal damage). + */ + damage = 1; + goto found_damage; + } if (DIFF_FILE_VALID(p->one) && DIFF_FILE_VALID(p->two)) { diff_populate_filespec(p->one, 0); @@@ -1591,18 -1564,14 +1591,18 @@@ /* * Original minus copied is the removed material, * added is the new material. They are both damages - * made to the preimage. In --dirstat-by-file mode, count - * damaged files, not damaged lines. This is done by - * counting only a single damaged line per file. + * made to the preimage. + * If the resulting damage is zero, we know that + * diffcore_count_changes() considers the two entries to + * be identical, but since content_changed is true, we + * know that there must have been _some_ kind of change, + * so we force all entries to have damage > 0. */ damage = (p->one->size - copied) + added; - if (DIFF_OPT_TST(options, DIRSTAT_BY_FILE) && damage > 0) + if (!damage) damage = 1; +found_damage: ALLOC_GROW(dir.files, dir.nr + 1, dir.alloc); dir.files[dir.nr].name = name; dir.files[dir.nr].changed = damage; @@@ -3987,6 -3956,28 +3987,28 @@@ static int is_summary_empty(const struc return 1; } + static const char rename_limit_warning[] = + "inexact rename detection was skipped due to too many files."; + + static const char degrade_cc_to_c_warning[] = + "only found copies from modified paths due to too many files."; + + static const char rename_limit_advice[] = + "you may want to set your %s variable to at least " + "%d and retry the command."; + + void diff_warn_rename_limit(const char *varname, int needed, int degraded_cc) + { + if (degraded_cc) + warning(degrade_cc_to_c_warning); + else if (needed) + warning(rename_limit_warning); + else + return; + if (0 < needed && needed < 32767) + warning(rename_limit_advice, varname, needed); + } + void diff_flush(struct diff_options *options) { struct diff_queue_struct *q = &diff_queued_diff; @@@ -4268,6 -4259,10 +4290,10 @@@ void diffcore_std(struct diff_options * int diff_result_code(struct diff_options *opt, int status) { int result = 0; + + diff_warn_rename_limit("diff.renamelimit", + opt->needed_rename_limit, + opt->degraded_cc_to_c); if (!DIFF_OPT_TST(opt, EXIT_WITH_STATUS) && !(opt->output_format & DIFF_FORMAT_CHECKDIFF)) return status; diff --combined merge-recursive.c index 7c12673553,3ae4d53cc5..fb3c874ff4 --- a/merge-recursive.c +++ b/merge-recursive.c @@@ -22,11 -22,6 +22,6 @@@ #include "dir.h" #include "submodule.h" - static const char rename_limit_advice[] = - "inexact rename detection was skipped because there were too many\n" - " files. You may want to set your merge.renamelimit variable to at least\n" - " %d and retry this merge."; - static struct tree *shift_tree_object(struct tree *one, struct tree *two, const char *subtree_shift) { @@@ -344,11 -339,10 +339,11 @@@ static void make_room_for_directories_o * make room for the corresponding directory. Such paths will * later be processed in process_df_entry() at the end. If * the corresponding directory ends up being removed by the - * merge, then the file will be reinstated at that time; - * otherwise, if the file is not supposed to be removed by the - * merge, the contents of the file will be placed in another - * unique filename. + * merge, then the file will be reinstated at that time + * (albeit with a different timestamp!); otherwise, if the + * file is not supposed to be removed by the merge, the + * contents of the file will be placed in another unique + * filename. * * NOTE: This function relies on the fact that entries for a * D/F conflict will appear adjacent in the index, with the @@@ -357,15 -351,9 +352,15 @@@ */ const char *last_file = NULL; int last_len = 0; - struct stage_data *last_e; int i; + /* + * Do not do any of this crazyness during the recursive; we don't + * even write anything to the working tree! + */ + if (o->call_depth) + return; + for (i = 0; i < entries->nr; i++) { const char *path = entries->items[i].string; int len = strlen(path); @@@ -393,6 -381,7 +388,6 @@@ if (S_ISREG(e->stages[2].mode) || S_ISLNK(e->stages[2].mode)) { last_file = path; last_len = len; - last_e = e; } else { last_file = NULL; } @@@ -967,6 -956,7 +962,6 @@@ static int process_renames(struct merge } for (i = 0, j = 0; i < a_renames->nr || j < b_renames->nr;) { - char *src; struct string_list *renames1, *renames2Dst; struct rename *ren1 = NULL, *ren2 = NULL; const char *branch1, *branch2; @@@ -1001,6 -991,7 +996,6 @@@ ren2 = ren1; ren1 = tmp; } - src = ren1->pair->one->path; ren1->dst_entry->processed = 1; ren1->src_entry->processed = 1; @@@ -1268,13 -1259,9 +1263,13 @@@ static int merge_content(struct merge_o } if (mfi.clean && !df_conflict_remains && - sha_eq(mfi.sha, a_sha) && mfi.mode == a.mode) + sha_eq(mfi.sha, a_sha) && mfi.mode == a.mode && + !o->call_depth && !lstat(path, &st)) { output(o, 3, "Skipped %s (merged same as existing)", path); - else + add_cacheinfo(mfi.mode, mfi.sha, path, + 0 /*stage*/, 1 /*refresh*/, 0 /*options*/); + return mfi.clean; + } else output(o, 2, "Auto-merging %s", path); if (!mfi.clean) { @@@ -1664,8 -1651,9 +1659,9 @@@ int merge_recursive(struct merge_option commit_list_insert(h2, &(*result)->parents->next); } flush_output(o); - if (o->needed_rename_limit) - warning(rename_limit_advice, o->needed_rename_limit); + if (show(o, 2)) + diff_warn_rename_limit("merge.renamelimit", + o->needed_rename_limit, 0); return clean; } diff --combined t/t4001-diff-rename.sh index cad85450b7,301f3a0e54..3dadf9b316 --- a/t/t4001-diff-rename.sh +++ b/t/t4001-diff-rename.sh @@@ -64,7 -64,7 +64,7 @@@ test_expect_success 'validate the output.' \ 'compare_diff_patch current expected' -test_expect_success 'favour same basenames over different ones' ' +test_expect_success C_LOCALE_OUTPUT 'favour same basenames over different ones' ' cp path1 another-path && git add another-path && git commit -m 1 && @@@ -73,8 -73,33 +73,33 @@@ git mv another-path subdir/path1 && git status | grep "renamed: .*path1 -> subdir/path1"' -test_expect_success 'favour same basenames even with minor differences' ' +test_expect_success C_LOCALE_OUTPUT 'favour same basenames even with minor differences' ' git show HEAD:path1 | sed "s/15/16/" > subdir/path1 && git status | grep "renamed: .*path1 -> subdir/path1"' + test_expect_success 'setup for many rename source candidates' ' + git reset --hard && + for i in 0 1 2 3 4 5 6 7 8 9; + do + for j in 0 1 2 3 4 5 6 7 8 9; + do + echo "$i$j" >"path$i$j" + done + done && + git add "path??" && + test_tick && + git commit -m "hundred" && + (cat path1; echo new) >new-path && + echo old >>path1 && + git add new-path path1 && + git diff -l 4 -C -C --cached --name-status >actual 2>actual.err && + sed -e "s/^\([CM]\)[0-9]* /\1 /" actual >actual.munged && + cat >expect <<-EOF && + C path1 new-path + M path1 + EOF + test_cmp expect actual.munged && + grep warning actual.err + ' + test_done