merge-recursive: option to specify rename threshold
authorKevin Ballard <kevin@sb.org>
Mon, 27 Sep 2010 23:58:25 +0000 (16:58 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 29 Sep 2010 20:15:56 +0000 (13:15 -0700)
The recursive merge strategy turns on rename detection but leaves the
rename threshold at the default. Add a strategy option to allow the user
to specify a rename threshold to use.

Signed-off-by: Kevin Ballard <kevin@sb.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/merge-strategies.txt
diff.c
diff.h
merge-recursive.c
merge-recursive.h

index 91faba5da9333c936376c6e91f9296bb15df5b0e..77f26061d66fa24c57e169e75cff542e1223e12e 100644 (file)
@@ -74,6 +74,10 @@ no-renormalize;;
        Disables the `renormalize` option.  This overrides the
        `merge.renormalize` configuration variable.
 
+rename-threshold=<n>;;
+       Controls the similarity threshold used for rename detection.
+       See also linkgit:git-diff[1] `-M`.
+
 subtree[=path];;
        This option is a more advanced form of 'subtree' strategy, where
        the strategy makes a guess on how two trees must be shifted to
diff --git a/diff.c b/diff.c
index 2332fa6798d9e40e83a07a318675e70d9b3169aa..45177db94b223d7d1adbb59aa76a927a8fd7564c 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -3219,7 +3219,7 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
        return 1;
 }
 
-static int parse_num(const char **cp_p)
+int parse_rename_score(const char **cp_p)
 {
        unsigned long num, scale;
        int ch, dot;
@@ -3265,7 +3265,7 @@ static int diff_scoreopt_parse(const char *opt)
        if (cmd != 'M' && cmd != 'C' && cmd != 'B')
                return -1; /* that is not a -M, -C nor -B option */
 
-       opt1 = parse_num(&opt);
+       opt1 = parse_rename_score(&opt);
        if (cmd != 'B')
                opt2 = 0;
        else {
@@ -3275,7 +3275,7 @@ static int diff_scoreopt_parse(const char *opt)
                        return -1; /* we expect -B80/99 or -B80 */
                else {
                        opt++;
-                       opt2 = parse_num(&opt);
+                       opt2 = parse_rename_score(&opt);
                }
        }
        if (*opt != 0)
diff --git a/diff.h b/diff.h
index 063d10ac2216071ef218fab2ad51c13787614acf..dbd50961f1b974c92587778dfb99295ec2e3804d 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -301,4 +301,6 @@ extern size_t fill_textconv(struct userdiff_driver *driver,
 
 extern struct userdiff_driver *get_textconv(struct diff_filespec *one);
 
+extern int parse_rename_score(const char **cp_p);
+
 #endif /* DIFF_H */
index 9b9f97e6afab1fb41463eb6176d08adbe235a803..148c550fee4775be7c8b5f5a7faf61f3f05f890a 100644 (file)
@@ -339,6 +339,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)
@@ -1525,6 +1526,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-threshold=")) {
+               const char *score = s + strlen("rename-threshold=");
+               if ((o->rename_score = parse_rename_score(&score)) == -1 || *score != 0)
+                       return -1;
+       }
        else
                return -1;
        return 0;
index d21b446a1df8add6f2824c77a8896b9098d5c0fa..54420f15560310cdaf695a0b89133465f2bc52ec 100644 (file)
@@ -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;