Thread (4 messages) flat view 4 messages, 1 author, 2016-06-15

[WIP/PATCH] merge-recursive: option to specify rename threshold

From: Kevin Ballard <hidden>
Date: 2016-06-15 22:49:35
Subsystem: the rest · Maintainer: Linus Torvalds

The recursive merge strategy turns on rename detection but leaves the
rename score at the default. Add a strategy option to allow the user
to specify a rename score to use.
---
The only thing I'm concerned about in this patch is the duplicated
parse_num() function. I'm inclined to take that function in diff.c,
rename it to something like parse_rename_score(), and declare it
in diff.h.

 merge-recursive.c |   43 +++++++++++++++++++++++++++++++++++++++++++
 merge-recursive.h |    1 +
 2 files changed, 44 insertions(+), 0 deletions(-)
diff --git a/merge-recursive.c b/merge-recursive.c
index bf611ae..f8ff30e 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -334,6 +334,7 @@ static struct string_list *get_renames(struct merge_options *o,
 	opts.rename_limit = o->merge_rename_limit >= 0 ? o->merge_rename_limit :
 			    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)
@@ -1552,6 +1553,43 @@ void init_merge_options(struct merge_options *o)
 	o->current_directory_set.strdup_strings = 1;
 }
 
+// XXX: copied from diff.c
+static int parse_num(const char **cp_p)
+{
+	unsigned long num, scale;
+	int ch, dot;
+	const char *cp = *cp_p;
+
+	num = 0;
+	scale = 1;
+	dot = 0;
+	for (;;) {
+		ch = *cp;
+		if ( !dot && ch == '.' ) {
+			scale = 1;
+			dot = 1;
+		} else if ( ch == '%' ) {
+			scale = dot ? scale*100 : 100;
+			cp++;	/* % is always at the end */
+			break;
+		} else if ( ch >= '0' && ch <= '9' ) {
+			if ( scale < 100000 ) {
+				scale *= 10;
+				num = (num*10) + (ch-'0');
+			}
+		} else {
+			break;
+		}
+		cp++;
+	}
+	*cp_p = cp;
+
+	/* user says num divided by scale and we say internally that
+	 * is MAX_SCORE * num / scale.
+	 */
+	return (int)((num >= scale) ? MAX_SCORE : (MAX_SCORE * num / scale));
+}
+
 int parse_merge_opt(struct merge_options *o, const char *s)
 {
 	if (!s || !*s)
@@ -1576,6 +1614,11 @@ int parse_merge_opt(struct merge_options *o, const char *s)
 		o->renormalize = 1;
 	else if (!strcmp(s, "no-renormalize"))
 		o->renormalize = 0;
+	else if (!prefixcmp(s, "rename-score=")) {
+		const char *score = s + strlen("rename-score=");
+		if ((o->rename_score = parse_num(&score)) == -1 || *score != 0)
+			return -1;
+	}
 	else
 		return -1;
 	return 0;
diff --git a/merge-recursive.h b/merge-recursive.h
index 2eb5d1a..c8135b0 100644
--- a/merge-recursive.h
+++ b/merge-recursive.h
@@ -19,6 +19,7 @@ struct merge_options {
 	int verbosity;
 	int diff_rename_limit;
 	int merge_rename_limit;
+	int rename_score;
 	int call_depth;
 	struct strbuf obuf;
 	struct string_list current_file_set;
-- 
1.7.3.237.ge0a7
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help