diff --git a/diff.c b/diff.c index 2ebe2227b4..b3ef25c345 100644 --- a/diff.c +++ b/diff.c @@ -5454,7 +5454,7 @@ void diff_warn_rename_limit(const char *varname, int needed, int degraded_cc) warning(_(rename_limit_warning)); else return; - if (0 < needed && needed < 32767) + if (0 < needed) warning(_(rename_limit_advice), varname, needed); } diff --git a/diffcore-rename.c b/diffcore-rename.c index 12dc2a056f..245e999fe5 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -391,14 +391,12 @@ static int too_many_rename_candidates(int num_create, * growing larger than a "rename_limit" square matrix, ie: * * num_create * num_src > rename_limit * rename_limit - * - * but handles the potential overflow case specially (and we - * assume at least 32-bit integers) */ - if (rename_limit <= 0 || rename_limit > 32767) + if (rename_limit <= 0) rename_limit = 32767; if ((num_create <= rename_limit || num_src <= rename_limit) && - (num_create * num_src <= rename_limit * rename_limit)) + ((uint64_t)num_create * (uint64_t)num_src + <= (uint64_t)rename_limit * (uint64_t)rename_limit)) return 0; options->needed_rename_limit = @@ -415,7 +413,8 @@ static int too_many_rename_candidates(int num_create, num_src++; } if ((num_create <= rename_limit || num_src <= rename_limit) && - (num_create * num_src <= rename_limit * rename_limit)) + ((uint64_t)num_create * (uint64_t)num_src + <= (uint64_t)rename_limit * (uint64_t)rename_limit)) return 2; return 1; } @@ -534,7 +533,7 @@ void diffcore_rename(struct diff_options *options) if (options->show_rename_progress) { progress = start_delayed_progress( _("Performing inexact rename detection"), - rename_dst_nr * rename_src_nr); + (uint64_t)rename_dst_nr * (uint64_t)rename_src_nr); } mx = xcalloc(st_mult(NUM_CANDIDATE_PER_DST, num_create), sizeof(*mx)); @@ -571,7 +570,7 @@ void diffcore_rename(struct diff_options *options) diff_free_filespec_blob(two); } dst_cnt++; - display_progress(progress, (i+1)*rename_src_nr); + display_progress(progress, (uint64_t)(i+1)*(uint64_t)rename_src_nr); } stop_progress(&progress); diff --git a/progress.c b/progress.c index 5f87f4568f..5a99c9fbf0 100644 --- a/progress.c +++ b/progress.c @@ -30,8 +30,8 @@ struct throughput { struct progress { const char *title; - int last_value; - unsigned total; + uint64_t last_value; + uint64_t total; unsigned last_percent; unsigned delay; struct throughput *throughput; @@ -78,7 +78,7 @@ static int is_foreground_fd(int fd) return tpgrp < 0 || tpgrp == getpgid(0); } -static int display(struct progress *progress, unsigned n, const char *done) +static int display(struct progress *progress, uint64_t n, const char *done) { const char *eol, *tp; @@ -93,9 +93,10 @@ static int display(struct progress *progress, unsigned n, const char *done) if (percent != progress->last_percent || progress_update) { progress->last_percent = percent; if (is_foreground_fd(fileno(stderr)) || done) { - fprintf(stderr, "%s: %3u%% (%u/%u)%s%s", - progress->title, percent, n, - progress->total, tp, eol); + fprintf(stderr, "%s: %3u%% (%"PRIuMAX"/%"PRIuMAX")%s%s", + progress->title, percent, + (uintmax_t)n, (uintmax_t)progress->total, + tp, eol); fflush(stderr); } progress_update = 0; @@ -103,8 +104,8 @@ static int display(struct progress *progress, unsigned n, const char *done) } } else if (progress_update) { if (is_foreground_fd(fileno(stderr)) || done) { - fprintf(stderr, "%s: %u%s%s", - progress->title, n, tp, eol); + fprintf(stderr, "%s: %"PRIuMAX"%s%s", + progress->title, (uintmax_t)n, tp, eol); fflush(stderr); } progress_update = 0; @@ -114,7 +115,7 @@ static int display(struct progress *progress, unsigned n, const char *done) return 0; } -static void throughput_string(struct strbuf *buf, off_t total, +static void throughput_string(struct strbuf *buf, uint64_t total, unsigned int rate) { strbuf_reset(buf); @@ -125,7 +126,7 @@ static void throughput_string(struct strbuf *buf, off_t total, strbuf_addstr(buf, "/s"); } -void display_throughput(struct progress *progress, off_t total) +void display_throughput(struct progress *progress, uint64_t total) { struct throughput *tp; uint64_t now_ns; @@ -187,12 +188,12 @@ void display_throughput(struct progress *progress, off_t total) display(progress, progress->last_value, NULL); } -int display_progress(struct progress *progress, unsigned n) +int display_progress(struct progress *progress, uint64_t n) { return progress ? display(progress, n, NULL) : 0; } -static struct progress *start_progress_delay(const char *title, unsigned total, +static struct progress *start_progress_delay(const char *title, uint64_t total, unsigned delay) { struct progress *progress = malloc(sizeof(*progress)); @@ -213,12 +214,12 @@ static struct progress *start_progress_delay(const char *title, unsigned total, return progress; } -struct progress *start_delayed_progress(const char *title, unsigned total) +struct progress *start_delayed_progress(const char *title, uint64_t total) { return start_progress_delay(title, total, 2); } -struct progress *start_progress(const char *title, unsigned total) +struct progress *start_progress(const char *title, uint64_t total) { return start_progress_delay(title, total, 0); } diff --git a/progress.h b/progress.h index 6392b63371..70a4d4a0d6 100644 --- a/progress.h +++ b/progress.h @@ -3,10 +3,10 @@ struct progress; -void display_throughput(struct progress *progress, off_t total); -int display_progress(struct progress *progress, unsigned n); -struct progress *start_progress(const char *title, unsigned total); -struct progress *start_delayed_progress(const char *title, unsigned total); +void display_throughput(struct progress *progress, uint64_t total); +int display_progress(struct progress *progress, uint64_t n); +struct progress *start_progress(const char *title, uint64_t total); +struct progress *start_delayed_progress(const char *title, uint64_t total); void stop_progress(struct progress **progress); void stop_progress_msg(struct progress **progress, const char *msg); diff --git a/sequencer.c b/sequencer.c index e90bc316bb..c8cb20c1eb 100644 --- a/sequencer.c +++ b/sequencer.c @@ -449,6 +449,7 @@ static int do_recursive_merge(struct commit *base, struct commit *next, o.branch2 = next ? next_label : "(empty tree)"; if (is_rebase_i(opts)) o.buffer_output = 2; + o.show_rename_progress = 1; head_tree = parse_tree_indirect(head); next_tree = next ? next->tree : empty_tree(); @@ -463,6 +464,7 @@ static int do_recursive_merge(struct commit *base, struct commit *next, if (is_rebase_i(opts) && clean <= 0) fputs(o.obuf.buf, stdout); strbuf_release(&o.obuf); + diff_warn_rename_limit("merge.renamelimit", o.needed_rename_limit, 0); if (clean < 0) return clean; diff --git a/t/t4001-diff-rename.sh b/t/t4001-diff-rename.sh index 0d1fa45d25..eadf4f6244 100755 --- a/t/t4001-diff-rename.sh +++ b/t/t4001-diff-rename.sh @@ -230,4 +230,19 @@ test_expect_success 'rename pretty print common prefix and suffix overlap' ' test_i18ngrep " d/f/{ => f}/e " output ' +test_expect_success 'diff-tree -l0 defaults to a big rename limit, not zero' ' + test_write_lines line1 line2 line3 >myfile && + git add myfile && + git commit -m x && + + test_write_lines line1 line2 line4 >myotherfile && + git rm myfile && + git add myotherfile && + git commit -m x && + + git diff-tree -M -l0 HEAD HEAD^ >actual && + # Verify that a rename from myotherfile to myfile was detected + grep "myotherfile.*myfile" actual +' + test_done