From bf0ab10fa84df6c49450a06077d1c52756d88222 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sat, 19 Feb 2011 05:20:51 -0500 Subject: merge: improve inexact rename limit warning The warning is generated deep in the diffcore code, which means that it will come first, followed possibly by a spew of conflicts, making it hard to see. Instead, let's have diffcore pass back the information about how big the rename limit would needed to have been, and then the caller can provide a more appropriate message (and at a more appropriate time). No refactoring of other non-merge callers is necessary, because nobody else was even using the warn_on_rename_limit feature. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- merge-recursive.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'merge-recursive.c') diff --git a/merge-recursive.c b/merge-recursive.c index 16c2dbeab..2ecd456c2 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -22,6 +22,11 @@ #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) { @@ -436,12 +441,13 @@ static struct string_list *get_renames(struct merge_options *o, o->diff_rename_limit >= 0 ? o->diff_rename_limit : 500; opts.rename_score = o->rename_score; - opts.warn_on_too_large_rename = 1; opts.output_format = DIFF_FORMAT_NO_OUTPUT; if (diff_setup_done(&opts) < 0) die("diff setup failed"); diff_tree_sha1(o_tree->object.sha1, tree->object.sha1, "", &opts); diffcore_std(&opts); + if (opts.needed_rename_limit > o->needed_rename_limit) + o->needed_rename_limit = opts.needed_rename_limit; for (i = 0; i < diff_queued_diff.nr; ++i) { struct string_list_item *item; struct rename *re; @@ -1666,6 +1672,8 @@ int merge_recursive(struct merge_options *o, commit_list_insert(h2, &(*result)->parents->next); } flush_output(o); + if (o->needed_rename_limit) + warning(rename_limit_advice, o->needed_rename_limit); return clean; } -- cgit v1.2.1 From 92c57e5c1d29db96a927e2a713c5aa4ae99ce749 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sat, 19 Feb 2011 05:21:28 -0500 Subject: bump rename limit defaults (again) We did this once before in 5070591 (bump rename limit defaults, 2008-04-30). Back then, we were shooting for about 1 second for a diff/log calculation, and 5 seconds for a merge. There are a few new things to consider, though: 1. Average processors are faster now. 2. We've seen on the mailing list some ugly merges where not using inexact rename detection leads to many more conflicts. Merges of this size take a long time anyway, so users are probably happy to spend a little bit of time computing the renames. Let's bump the diff/merge default limits from 200/500 to 400/1000. Those are 2 seconds and 10 seconds respectively on my modern hardware. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- merge-recursive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'merge-recursive.c') diff --git a/merge-recursive.c b/merge-recursive.c index 2ecd456c2..089aa10cc 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -439,7 +439,7 @@ static struct string_list *get_renames(struct merge_options *o, opts.detect_rename = DIFF_DETECT_RENAME; opts.rename_limit = o->merge_rename_limit >= 0 ? o->merge_rename_limit : o->diff_rename_limit >= 0 ? o->diff_rename_limit : - 500; + 1000; opts.rename_score = o->rename_score; opts.output_format = DIFF_FORMAT_NO_OUTPUT; if (diff_setup_done(&opts) < 0) -- cgit v1.2.1 From 99bfc6691d79eaffaaf170a8b6584bcfe97863dc Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sun, 20 Feb 2011 04:53:21 -0500 Subject: merge: enable progress reporting for rename detection The user can enable or disable it explicitly with the new --progress, but it defaults to checking isatty(2). This works only with merge-recursive and subtree. In theory we could pass a progress flag to other strategies, but none of them support progress at this point, so let's wait until they grow such a feature before worrying about propagating it. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- merge-recursive.c | 1 + 1 file changed, 1 insertion(+) (limited to 'merge-recursive.c') diff --git a/merge-recursive.c b/merge-recursive.c index 089aa10cc..6c8f95771 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -441,6 +441,7 @@ static struct string_list *get_renames(struct merge_options *o, o->diff_rename_limit >= 0 ? o->diff_rename_limit : 1000; opts.rename_score = o->rename_score; + opts.show_rename_progress = o->show_rename_progress; opts.output_format = DIFF_FORMAT_NO_OUTPUT; if (diff_setup_done(&opts) < 0) die("diff setup failed"); -- cgit v1.2.1 From ebeb60900fbab569ed14f710a0a1abb1637ec792 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 25 Feb 2011 23:08:53 -0600 Subject: strbuf: add strbuf_vaddf In a variable-args function, the code for writing into a strbuf is non-trivial. We ended up cutting and pasting it in several places because there was no vprintf-style function for strbufs (which in turn was held up by a lack of va_copy). Now that we have a fallback va_copy, we can add strbuf_vaddf, the strbuf equivalent of vsprintf. And we can clean up the cut and paste mess. Signed-off-by: Jeff King Improved-by: Christian Couder Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- merge-recursive.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'merge-recursive.c') diff --git a/merge-recursive.c b/merge-recursive.c index 16c2dbeab..2a4f73936 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -137,7 +137,6 @@ static void flush_output(struct merge_options *o) __attribute__((format (printf, 3, 4))) static void output(struct merge_options *o, int v, const char *fmt, ...) { - int len; va_list ap; if (!show(o, v)) @@ -148,21 +147,9 @@ static void output(struct merge_options *o, int v, const char *fmt, ...) strbuf_setlen(&o->obuf, o->obuf.len + o->call_depth * 2); va_start(ap, fmt); - len = vsnprintf(o->obuf.buf + o->obuf.len, strbuf_avail(&o->obuf), fmt, ap); + strbuf_vaddf(&o->obuf, fmt, ap); va_end(ap); - if (len < 0) - len = 0; - if (len >= strbuf_avail(&o->obuf)) { - strbuf_grow(&o->obuf, len + 2); - va_start(ap, fmt); - len = vsnprintf(o->obuf.buf + o->obuf.len, strbuf_avail(&o->obuf), fmt, ap); - va_end(ap); - if (len >= strbuf_avail(&o->obuf)) { - die("this should not happen, your snprintf is broken"); - } - } - strbuf_setlen(&o->obuf, o->obuf.len + len); strbuf_add(&o->obuf, "\n", 1); if (!o->buffer_output) flush_output(o); -- cgit v1.2.1 From 13ee1384ef0004bd9fa6e4d2b832b49ce2e8a032 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Sun, 27 Mar 2011 20:32:19 -0500 Subject: Fix two unused variable warnings in gcc 4.6 Seen with -Wunused-but-set-variable. Signed-off-by: Dan McGee Signed-off-by: Junio C Hamano --- merge-recursive.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'merge-recursive.c') diff --git a/merge-recursive.c b/merge-recursive.c index 8e82a8b1a..af131508e 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -356,7 +356,6 @@ static void make_room_for_directories_of_df_conflicts(struct merge_options *o, */ const char *last_file = NULL; int last_len = 0; - struct stage_data *last_e; int i; for (i = 0; i < entries->nr; i++) { @@ -386,7 +385,6 @@ static void make_room_for_directories_of_df_conflicts(struct merge_options *o, 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; } @@ -961,7 +959,6 @@ static int process_renames(struct merge_options *o, } 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; @@ -996,7 +993,6 @@ static int process_renames(struct merge_options *o, ren2 = ren1; ren1 = tmp; } - src = ren1->pair->one->path; ren1->dst_entry->processed = 1; ren1->src_entry->processed = 1; -- cgit v1.2.1