535
result->util = mi;
536
}
537
538
+static void add_pair(struct merge_options *opt,
539
+ struct name_entry *names,
540
+ const char *pathname,
541
+ unsigned side,
542
+ unsigned is_add /* if false, is_delete */)
543
+{
544
+ struct diff_filespec *one, *two;
545
+ struct rename_info *renames = &opt->priv->renames;
546
+ int names_idx = is_add ? side : 0;
547
+
548
+ one = alloc_filespec(pathname);
549
+ two = alloc_filespec(pathname);
550
+ fill_filespec(is_add ? two : one,
551
+ &names[names_idx].oid, 1, names[names_idx].mode);
552
+ diff_queue(&renames->pairs[side], one, two);
553
+}
554
+
555
static void collect_rename_info(struct merge_options *opt,
556
struct name_entry *names,
557
const char *dirname,
561
unsigned match_mask)
562
{
563
struct rename_info *renames = &opt->priv->renames;
564
+ unsigned side;
565
566
/* Update dirs_removed, as needed */
567
if (dirmask == 1 || dirmask == 3 || dirmask == 5) {
572
if (sides & 2)
573
strset_add(&renames->dirs_removed[2], fullname);
574
}
575
+
576
+ if (filemask == 0 || filemask == 7)
577
+ return;
578
+
579
+ for (side = MERGE_SIDE1; side <= MERGE_SIDE2; ++side) {
580
+ unsigned side_mask = (1 << side);
581
+
582
+ /* Check for deletion on side */
583
+ if ((filemask & 1) && !(filemask & side_mask))
584
+ add_pair(opt, names, fullname, side, 0 /* delete */);
585
+
586
+ /* Check for addition on side */
587
+ if (!(filemask & 1) && (filemask & side_mask))
588
+ add_pair(opt, names, fullname, side, 1 /* add */);
589
+ }
590
}
591
592
static int collect_merge_info_callback(int n,
2112
return clean_merge;
2113
}
2114
2115
+static void resolve_diffpair_statuses(struct diff_queue_struct *q)
2116
+{
2117
+ /*
2118
+ * A simplified version of diff_resolve_rename_copy(); would probably
2119
+ * just use that function but it's static...
2120
+ */
2121
+ int i;
2122
+ struct diff_filepair *p;
2123
+
2124
+ for (i = 0; i < q->nr; ++i) {
2125
+ p = q->queue[i];
2126
+ p->status = 0; /* undecided */
2127
+ if (!DIFF_FILE_VALID(p->one))
2128
+ p->status = DIFF_STATUS_ADDED;
2129
+ else if (!DIFF_FILE_VALID(p->two))
2130
+ p->status = DIFF_STATUS_DELETED;
2131
+ else if (DIFF_PAIR_RENAME(p))
2132
+ p->status = DIFF_STATUS_RENAMED;
2133
+ }
2134
+}
2135
+
2136
static int compare_pairs(const void *a_, const void *b_)
2137
{
2138
const struct diff_filepair *a = *((const struct diff_filepair **)a_);
2143
2144
/* Call diffcore_rename() to compute which files have changed on given side */
2145
static void detect_regular_renames(struct merge_options *opt,
2092
- struct tree *merge_base,
2093
- struct tree *side,
2146
unsigned side_index)
2147
{
2148
struct diff_options diff_opts;
2160
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
2161
diff_setup_done(&diff_opts);
2162
2163
+ diff_queued_diff = renames->pairs[side_index];
2164
trace2_region_enter("diff", "diffcore_rename", opt->repo);
2112
- diff_tree_oid(&merge_base->object.oid, &side->object.oid, "",
2113
- &diff_opts);
2114
- diffcore_std(&diff_opts);
2165
+ diffcore_rename(&diff_opts);
2166
trace2_region_leave("diff", "diffcore_rename", opt->repo);
2167
+ resolve_diffpair_statuses(&diff_queued_diff);
2168
2169
if (diff_opts.needed_rename_limit > renames->needed_limit)
2170
renames->needed_limit = diff_opts.needed_rename_limit;
2264
memset(&combined, 0, sizeof(combined));
2265
2266
trace2_region_enter("merge", "regular renames", opt->repo);
2215
- detect_regular_renames(opt, merge_base, side1, MERGE_SIDE1);
2216
- detect_regular_renames(opt, merge_base, side2, MERGE_SIDE2);
2267
+ detect_regular_renames(opt, MERGE_SIDE1);
2268
+ detect_regular_renames(opt, MERGE_SIDE2);
2269
trace2_region_leave("merge", "regular renames", opt->repo);
2270
2271
trace2_region_enter("merge", "directory renames", opt->repo);