aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--diff.c27
-rw-r--r--diff.h3
-rw-r--r--diffcore.h2
-rw-r--r--tree-diff.c11
4 files changed, 27 insertions, 16 deletions
diff --git a/diff.c b/diff.c
index bf65892f7..93004922d 100644
--- a/diff.c
+++ b/diff.c
@@ -4064,25 +4064,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))
@@ -4090,7 +4089,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)
diff --git a/diff.h b/diff.h
index 063d10ac2..6fff024e3 100644
--- a/diff.h
+++ b/diff.h
@@ -126,6 +126,9 @@ struct diff_options {
/* this is set by diffcore for DIFF_FORMAT_PATCH */
int found_changes;
+ /* to support internal diff recursion by --follow hack*/
+ int found_follow;
+
FILE *file;
int close_file;
diff --git a/diffcore.h b/diffcore.h
index 05ebc115a..8b3241ad1 100644
--- a/diffcore.h
+++ b/diffcore.h
@@ -91,13 +91,11 @@ struct diff_queue_struct {
struct diff_filepair **queue;
int alloc;
int nr;
- int run;
};
#define DIFF_QUEUE_CLEAR(q) \
do { \
(q)->queue = NULL; \
(q)->nr = (q)->alloc = 0; \
- (q)->run = 0; \
} while (0)
extern struct diff_queue_struct diff_queued_diff;
diff --git a/tree-diff.c b/tree-diff.c
index 5b68c0864..cd659c6fe 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -359,6 +359,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
diff_tree_release_paths(&diff_opts);
/* Go through the new set of filepairing, and see if we find a more interesting one */
+ opt->found_follow = 0;
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
@@ -376,6 +377,16 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
diff_tree_release_paths(opt);
opt->paths[0] = xstrdup(p->one->path);
diff_tree_setup_paths(opt->paths, opt);
+
+ /*
+ * The caller expects us to return a set of vanilla
+ * filepairs to let a later call to diffcore_std()
+ * it makes to sort the renames out (among other
+ * things), but we already have found renames
+ * ourselves; signal diffcore_std() not to muck with
+ * rename information.
+ */
+ opt->found_follow = 1;
break;
}
}