186
enum rename_type {
187
RENAME_NORMAL = 0,
188
RENAME_VIA_DIR,
189
+ RENAME_ADD,
190
RENAME_DELETE,
191
RENAME_ONE_FILE_TO_ONE,
192
RENAME_ONE_FILE_TO_TWO,
229
struct stage_data *src_entry1,
230
struct stage_data *src_entry2)
231
{
232
+ int ostage1 = 0, ostage2;
233
struct rename_conflict_info *ci;
234
235
/*
266
dst_entry2->rename_conflict_info = ci;
267
}
268
267
- if (rename_type == RENAME_TWO_FILES_TO_ONE) {
268
- /*
269
- * For each rename, there could have been
270
- * modifications on the side of history where that
271
- * file was not renamed.
272
- */
273
- int ostage1 = o->branch1 == branch1 ? 3 : 2;
274
- int ostage2 = ostage1 ^ 1;
269
+ /*
270
+ * For each rename, there could have been
271
+ * modifications on the side of history where that
272
+ * file was not renamed.
273
+ */
274
+ if (rename_type == RENAME_ADD ||
275
+ rename_type == RENAME_TWO_FILES_TO_ONE) {
276
+ ostage1 = o->branch1 == branch1 ? 3 : 2;
277
278
ci->ren1_other.path = pair1->one->path;
279
oidcpy(&ci->ren1_other.oid, &src_entry1->stages[ostage1].oid);
280
ci->ren1_other.mode = src_entry1->stages[ostage1].mode;
281
+ }
282
+
283
+ if (rename_type == RENAME_TWO_FILES_TO_ONE) {
284
+ ostage2 = ostage1 ^ 1;
285
286
ci->ren2_other.path = pair2->one->path;
287
oidcpy(&ci->ren2_other.oid, &src_entry2->stages[ostage2].oid);
1565
return target;
1566
}
1567
1562
-#if 0 // #if-0-ing avoids unused function warning; will make live in next commit
1568
static int handle_file_collision(struct merge_options *o,
1569
const char *collide_path,
1570
const char *prev_path1,
1580
char *alt_path = NULL;
1581
const char *update_path = collide_path;
1582
1583
+ /*
1584
+ * It's easiest to get the correct things into stage 2 and 3, and
1585
+ * to make sure that the content merge puts HEAD before the other
1586
+ * branch if we just ensure that branch1 == o->branch1. So, simply
1587
+ * flip arguments around if we don't have that.
1588
+ */
1589
+ if (branch1 != o->branch1) {
1590
+ return handle_file_collision(o, collide_path,
1591
+ prev_path2, prev_path1,
1592
+ branch2, branch1,
1593
+ b_oid, b_mode,
1594
+ a_oid, a_mode);
1595
+ }
1596
+
1597
/*
1598
* In the recursive case, we just opt to undo renames
1599
*/
1697
*/
1698
return mfi.clean;
1699
}
1681
-#endif
1700
+
1701
+static int handle_rename_add(struct merge_options *o,
1702
+ struct rename_conflict_info *ci)
1703
+{
1704
+ /* a was renamed to c, and a separate c was added. */
1705
+ struct diff_filespec *a = ci->pair1->one;
1706
+ struct diff_filespec *c = ci->pair1->two;
1707
+ char *path = c->path;
1708
+ char *prev_path_desc;
1709
+ struct merge_file_info mfi;
1710
+
1711
+ int other_stage = (ci->branch1 == o->branch1 ? 3 : 2);
1712
+
1713
+ output(o, 1, _("CONFLICT (rename/add): "
1714
+ "Rename %s->%s in %s. Added %s in %s"),
1715
+ a->path, c->path, ci->branch1,
1716
+ c->path, ci->branch2);
1717
+
1718
+ prev_path_desc = xstrfmt("version of %s from %s", path, a->path);
1719
+ if (merge_mode_and_contents(o, a, c, &ci->ren1_other, prev_path_desc,
1720
+ o->branch1, o->branch2,
1721
+ 1 + o->call_depth * 2, &mfi))
1722
+ return -1;
1723
+ free(prev_path_desc);
1724
+
1725
+ return handle_file_collision(o,
1726
+ c->path, a->path, NULL,
1727
+ ci->branch1, ci->branch2,
1728
+ &mfi.oid, mfi.mode,
1729
+ &ci->dst_entry1->stages[other_stage].oid,
1730
+ ci->dst_entry1->stages[other_stage].mode);
1731
+}
1732
1733
static int handle_file(struct merge_options *o,
1734
struct diff_filespec *rename,
2910
0 /* update_wd */))
2911
clean_merge = -1;
2912
} else if (!oid_eq(&dst_other.oid, &null_oid)) {
2863
- clean_merge = 0;
2864
- try_merge = 1;
2865
- output(o, 1, _("CONFLICT (rename/add): Rename %s->%s in %s. "
2866
- "%s added in %s"),
2867
- ren1_src, ren1_dst, branch1,
2868
- ren1_dst, branch2);
2869
- if (o->call_depth) {
2870
- struct merge_file_info mfi;
2871
- struct diff_filespec one, a, b;
2872
-
2873
- oidcpy(&one.oid, &null_oid);
2874
- one.mode = 0;
2875
- one.path = ren1->pair->two->path;
2876
-
2877
- oidcpy(&a.oid, &ren1->pair->two->oid);
2878
- a.mode = ren1->pair->two->mode;
2879
- a.path = one.path;
2880
-
2881
- oidcpy(&b.oid, &dst_other.oid);
2882
- b.mode = dst_other.mode;
2883
- b.path = one.path;
2884
-
2885
- if (merge_mode_and_contents(o, &one, &a, &b, ren1_dst,
2886
- branch1, branch2,
2887
- o->call_depth * 2, &mfi)) {
2888
- clean_merge = -1;
2889
- goto cleanup_and_return;
2890
- }
2891
- output(o, 1, _("Adding merged %s"), ren1_dst);
2892
- if (update_file(o, 0, &mfi.oid,
2893
- mfi.mode, ren1_dst))
2894
- clean_merge = -1;
2895
- try_merge = 0;
2896
- } else {
2897
- char *new_path = unique_path(o, ren1_dst, branch2);
2898
- output(o, 1, _("Adding as %s instead"), new_path);
2899
- if (update_file(o, 0, &dst_other.oid,
2900
- dst_other.mode, new_path))
2901
- clean_merge = -1;
2902
- free(new_path);
2903
- }
2913
+ /*
2914
+ * Probably not a clean merge, but it's
2915
+ * premature to set clean_merge to 0 here,
2916
+ * because if the rename merges cleanly and
2917
+ * the merge exactly matches the newly added
2918
+ * file, then the merge will be clean.
2919
+ */
2920
+ setup_rename_conflict_info(RENAME_ADD,
2921
+ ren1->pair,
2922
+ NULL,
2923
+ branch1,
2924
+ branch2,
2925
+ ren1->dst_entry,
2926
+ NULL,
2927
+ o,
2928
+ ren1->src_entry,
2929
+ NULL);
2930
} else
2931
try_merge = 1;
2932
3338
conflict_info->branch2))
3339
clean_merge = -1;
3340
break;
3341
+ case RENAME_ADD:
3342
+ /*
3343
+ * Probably unclean merge, but if the renamed file
3344
+ * merges cleanly and the result can then be
3345
+ * two-way merged cleanly with the added file, I
3346
+ * guess it's a clean merge?
3347
+ */
3348
+ clean_merge = handle_rename_add(o, conflict_info);
3349
+ break;
3350
case RENAME_DELETE:
3351
clean_merge = 0;
3352
if (handle_rename_delete(o,