Code

t1510: setup case #30
[git.git] / diff.c
diff --git a/diff.c b/diff.c
index 6fb97d4623192167e9b9f83b02dfe9250f028c0a..d1c6b91982ccbb6489c57c9bbddb692c7b4b7ca3 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -919,7 +919,10 @@ static void free_diff_words_data(struct emit_callback *ecbdata)
                free (ecbdata->diff_words->minus.orig);
                free (ecbdata->diff_words->plus.text.ptr);
                free (ecbdata->diff_words->plus.orig);
-               free(ecbdata->diff_words->word_regex);
+               if (ecbdata->diff_words->word_regex) {
+                       regfree(ecbdata->diff_words->word_regex);
+                       free(ecbdata->diff_words->word_regex);
+               }
                free(ecbdata->diff_words);
                ecbdata->diff_words = NULL;
        }
@@ -3137,16 +3140,19 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
                return stat_opt(options, av);
 
        /* renames options */
-       else if (!prefixcmp(arg, "-B")) {
+       else if (!prefixcmp(arg, "-B") || !prefixcmp(arg, "--break-rewrites=") ||
+                !strcmp(arg, "--break-rewrites")) {
                if ((options->break_opt = diff_scoreopt_parse(arg)) == -1)
                        return -1;
        }
-       else if (!prefixcmp(arg, "-M")) {
+       else if (!prefixcmp(arg, "-M") || !prefixcmp(arg, "--detect-renames=") ||
+                !strcmp(arg, "--detect-renames")) {
                if ((options->rename_score = diff_scoreopt_parse(arg)) == -1)
                        return -1;
                options->detect_rename = DIFF_DETECT_RENAME;
        }
-       else if (!prefixcmp(arg, "-C")) {
+       else if (!prefixcmp(arg, "-C") || !prefixcmp(arg, "--detect-copies=") ||
+                !strcmp(arg, "--detect-copies")) {
                if (options->detect_rename == DIFF_DETECT_COPY)
                        DIFF_OPT_SET(options, FIND_COPIES_HARDER);
                if ((options->rename_score = diff_scoreopt_parse(arg)) == -1)
@@ -3268,12 +3274,17 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
        }
        else if ((argcount = short_opt('S', av, &optarg))) {
                options->pickaxe = optarg;
+               options->pickaxe_opts |= DIFF_PICKAXE_KIND_S;
+               return argcount;
+       } else if ((argcount = short_opt('G', av, &optarg))) {
+               options->pickaxe = optarg;
+               options->pickaxe_opts |= DIFF_PICKAXE_KIND_G;
                return argcount;
        }
        else if (!strcmp(arg, "--pickaxe-all"))
-               options->pickaxe_opts = DIFF_PICKAXE_ALL;
+               options->pickaxe_opts |= DIFF_PICKAXE_ALL;
        else if (!strcmp(arg, "--pickaxe-regex"))
-               options->pickaxe_opts = DIFF_PICKAXE_REGEX;
+               options->pickaxe_opts |= DIFF_PICKAXE_REGEX;
        else if ((argcount = short_opt('O', av, &optarg))) {
                options->orderfile = optarg;
                return argcount;
@@ -3307,7 +3318,7 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
        else if ((argcount = parse_long_opt("output", av, &optarg))) {
                options->file = fopen(optarg, "w");
                if (!options->file)
-                       die_errno("Could not open '%s'", arg + strlen("--output="));
+                       die_errno("Could not open '%s'", optarg);
                options->close_file = 1;
                return argcount;
        } else
@@ -3315,7 +3326,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;
@@ -3358,10 +3369,26 @@ static int diff_scoreopt_parse(const char *opt)
        if (*opt++ != '-')
                return -1;
        cmd = *opt++;
+       if (cmd == '-') {
+               /* convert the long-form arguments into short-form versions */
+               if (!prefixcmp(opt, "break-rewrites")) {
+                       opt += strlen("break-rewrites");
+                       if (*opt == 0 || *opt++ == '=')
+                               cmd = 'B';
+               } else if (!prefixcmp(opt, "detect-copies")) {
+                       opt += strlen("detect-copies");
+                       if (*opt == 0 || *opt++ == '=')
+                               cmd = 'C';
+               } else if (!prefixcmp(opt, "detect-renames")) {
+                       opt += strlen("detect-renames");
+                       if (*opt == 0 || *opt++ == '=')
+                               cmd = 'M';
+               }
+       }
        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 {
@@ -3371,7 +3398,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)
@@ -3524,7 +3551,7 @@ static void diff_flush_stat(struct diff_filepair *p, struct diff_options *o,
 
        if ((DIFF_FILE_VALID(p->one) && S_ISDIR(p->one->mode)) ||
            (DIFF_FILE_VALID(p->two) && S_ISDIR(p->two->mode)))
-               return; /* no tree diffs in patch format */
+               return; /* no useful stat for tree diffs */
 
        run_diffstat(p, o, diffstat);
 }
@@ -3537,7 +3564,7 @@ static void diff_flush_checkdiff(struct diff_filepair *p,
 
        if ((DIFF_FILE_VALID(p->one) && S_ISDIR(p->one->mode)) ||
            (DIFF_FILE_VALID(p->two) && S_ISDIR(p->two->mode)))
-               return; /* no tree diffs in patch format */
+               return; /* nothing to check in tree diffs */
 
        run_checkdiff(p, o);
 }
@@ -3853,6 +3880,13 @@ static int diff_get_patch_id(struct diff_options *options, unsigned char *sha1)
                                        len2, p->two->path);
                git_SHA1_Update(&ctx, buffer, len1);
 
+               if (diff_filespec_is_binary(p->one) ||
+                   diff_filespec_is_binary(p->two)) {
+                       git_SHA1_Update(&ctx, sha1_to_hex(p->one->sha1), 40);
+                       git_SHA1_Update(&ctx, sha1_to_hex(p->two->sha1), 40);
+                       continue;
+               }
+
                xpp.flags = 0;
                xecfg.ctxlen = 3;
                xecfg.flags = XDL_EMIT_FUNCNAMES;
@@ -4166,7 +4200,7 @@ void diffcore_std(struct diff_options *options)
                        diffcore_merge_broken();
        }
        if (options->pickaxe)
-               diffcore_pickaxe(options->pickaxe, options->pickaxe_opts);
+               diffcore_pickaxe(options);
        if (options->orderfile)
                diffcore_order(options->orderfile);
        if (!options->found_follow)