merge-recursive: Record more data needed for merging with dual renames
When two different files are renamed to one, we need to be able to do three-way merges for both of those files. To do that, we need to record the sha1sum of the (possibly modified) file on the unrenamed side. Modify setup_rename_conflict_info() to take this extra information and record it when the rename_type is RENAME_TWO_FILES_TO_ONE. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Elijah Newren committed
Aug 11, 2011 at 23:20 UTC
232c635f7e22acb2ddf526753fdcd3d3718afe99
1 file changed
+39
-3
merge-recursive.c
+39
-3
@@ -79,6 +79,8 @@ struct rename_conflict_info {
79
const char *branch2;
80
struct stage_data *dst_entry1;
81
struct stage_data *dst_entry2;
82
+ struct diff_filespec ren1_other;
83
+ struct diff_filespec ren2_other;
84
};
85
86
/*
@@ -100,7 +102,10 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type,
102
const char *branch1,
103
const char *branch2,
104
struct stage_data *dst_entry1,
103
- struct stage_data *dst_entry2)
105
+ struct stage_data *dst_entry2,
106
+ struct merge_options *o,
107
+ struct stage_data *src_entry1,
108
+ struct stage_data *src_entry2)
109
{
110
struct rename_conflict_info *ci = xcalloc(1, sizeof(struct rename_conflict_info));
111
ci->rename_type = rename_type;
@@ -118,6 +123,24 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type,
123
ci->pair2 = pair2;
124
dst_entry2->rename_conflict_info = ci;
125
}
126
+
127
+ if (rename_type == RENAME_TWO_FILES_TO_ONE) {
128
+ /*
129
+ * For each rename, there could have been
130
+ * modifications on the side of history where that
131
+ * file was not renamed.
132
+ */
133
+ int ostage1 = o->branch1 == branch1 ? 3 : 2;
134
+ int ostage2 = ostage1 ^ 1;
135
+
136
+ ci->ren1_other.path = pair1->one->path;
137
+ hashcpy(ci->ren1_other.sha1, src_entry1->stages[ostage1].sha);
138
+ ci->ren1_other.mode = src_entry1->stages[ostage1].mode;
139
+
140
+ ci->ren2_other.path = pair2->one->path;
141
+ hashcpy(ci->ren2_other.sha1, src_entry2->stages[ostage2].sha);
142
+ ci->ren2_other.mode = src_entry2->stages[ostage2].mode;
143
+ }
144
}
145
146
static int show(struct merge_options *o, int v)
@@ -1158,7 +1181,10 @@ static int process_renames(struct merge_options *o,
1181
branch1,
1182
branch2,
1183
ren1->dst_entry,
1161
- ren2->dst_entry);
1184
+ ren2->dst_entry,
1185
+ o,
1186
+ NULL,
1187
+ NULL);
1188
} else if ((lookup = string_list_lookup(renames2Dst, ren1_dst))) {
1189
/* Two different files renamed to the same thing */
1190
char *ren2_dst;
@@ -1182,7 +1208,11 @@ static int process_renames(struct merge_options *o,
1208
branch1,
1209
branch2,
1210
ren1->dst_entry,
1185
- ren2->dst_entry);
1211
+ ren2->dst_entry,
1212
+ o,
1213
+ ren1->src_entry,
1214
+ ren2->src_entry);
1215
+
1216
} else {
1217
/* Renamed in 1, maybe changed in 2 */
1218
/* we only use sha1 and mode of these */
@@ -1218,6 +1248,9 @@ static int process_renames(struct merge_options *o,
1248
branch1,
1249
branch2,
1250
ren1->dst_entry,
1251
+ NULL,
1252
+ o,
1253
+ NULL,
1254
NULL);
1255
} else if ((dst_other.mode == ren1->pair->two->mode) &&
1256
sha_eq(dst_other.sha1, ren1->pair->two->sha1)) {
@@ -1269,6 +1302,9 @@ static int process_renames(struct merge_options *o,
1302
branch1,
1303
NULL,
1304
ren1->dst_entry,
1305
+ NULL,
1306
+ o,
1307
+ NULL,
1308
NULL);
1309
}
1310
}