Code

git-reset.txt: reset does not change files in target
[git.git] / diff.c
diff --git a/diff.c b/diff.c
index 3aa695df62d2f13beed4b4ac54e3ea568194ae02..19b5bf63ed37aa49c00e63f7aec621ce601b6daa 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -912,7 +912,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;
        }
@@ -2627,8 +2630,7 @@ static void fill_metainfo(struct strbuf *msg,
                            (!fill_mmfile(&mf, two) && diff_filespec_is_binary(two)))
                                abbrev = 40;
                }
-               strbuf_addf(msg, "%s%sindex %s..", set,
-                           line_prefix,
+               strbuf_addf(msg, "%s%sindex %s..", line_prefix, set,
                            find_unique_abbrev(one->sha1, abbrev));
                strbuf_addstr(msg, find_unique_abbrev(two->sha1, abbrev));
                if (one->mode == two->mode)
@@ -2705,10 +2707,16 @@ static void diff_fill_sha1_info(struct diff_filespec *one)
 static void strip_prefix(int prefix_length, const char **namep, const char **otherp)
 {
        /* Strip the prefix but do not molest /dev/null and absolute paths */
-       if (*namep && **namep != '/')
+       if (*namep && **namep != '/') {
                *namep += prefix_length;
-       if (*otherp && **otherp != '/')
+               if (**namep == '/')
+                       ++*namep;
+       }
+       if (*otherp && **otherp != '/') {
                *otherp += prefix_length;
+               if (**otherp == '/')
+                       ++*otherp;
+       }
 }
 
 static void run_diff(struct diff_filepair *p, struct diff_options *o)
@@ -2815,7 +2823,6 @@ static void run_checkdiff(struct diff_filepair *p, struct diff_options *o)
 void diff_setup(struct diff_options *options)
 {
        memset(options, 0, sizeof(*options));
-       memset(&diff_queued_diff, 0, sizeof(diff_queued_diff));
 
        options->file = stdout;
 
@@ -4060,25 +4067,24 @@ void diffcore_fix_diff_index(struct diff_options *options)
 
 void diffcore_std(struct diff_options *options)
 {
-       /* We never run this function more than one time, because the
-        * rename/copy detection logic can only run once.
-        */
-       if (diff_queued_diff.run)
-               return;
-
        if (options->skip_stat_unmatch)
                diffcore_skip_stat_unmatch(options);
-       if (options->break_opt != -1)
-               diffcore_break(options->break_opt);
-       if (options->detect_rename)
-               diffcore_rename(options);
-       if (options->break_opt != -1)
-               diffcore_merge_broken();
+       if (!options->found_follow) {
+               /* See try_to_follow_renames() in tree-diff.c */
+               if (options->break_opt != -1)
+                       diffcore_break(options->break_opt);
+               if (options->detect_rename)
+                       diffcore_rename(options);
+               if (options->break_opt != -1)
+                       diffcore_merge_broken();
+       }
        if (options->pickaxe)
                diffcore_pickaxe(options->pickaxe, options->pickaxe_opts);
        if (options->orderfile)
                diffcore_order(options->orderfile);
-       diff_resolve_rename_copy();
+       if (!options->found_follow)
+               /* See try_to_follow_renames() in tree-diff.c */
+               diff_resolve_rename_copy();
        diffcore_apply_filter(options->filter);
 
        if (diff_queued_diff.nr && !DIFF_OPT_TST(options, DIFF_FROM_CONTENTS))
@@ -4086,7 +4092,7 @@ void diffcore_std(struct diff_options *options)
        else
                DIFF_OPT_CLR(options, HAS_CHANGES);
 
-       diff_queued_diff.run = 1;
+       options->found_follow = 0;
 }
 
 int diff_result_code(struct diff_options *opt, int status)