merge-recursive: track information associated with directory renames
Directory rename detection previously silently applied. In order to allow printing information about paths that changed or printing a conflict notification (and only doing so near other potential conflict messages associated with the paths), save this information inside the rename struct for later use. A subsequent patch will make use of the additional information. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Elijah Newren committed
Apr 5, 2019 at 08:00 UTC
6d169fd321c0da4b20c13d08bbe19d55cab12e11
1 file changed
+23
-14
merge-recursive.c
+23
-14
@@ -207,8 +207,16 @@ struct stage_data {
207
};
208
209
struct rename {
210
+ unsigned processed:1;
211
struct diff_filepair *pair;
212
const char *branch; /* branch that the rename occurred on */
213
+ /*
214
+ * If directory rename detection affected this rename, what was its
215
+ * original type ('A' or 'R') and it's original destination before
216
+ * the directory rename (otherwise, '\0' and NULL for these two vars).
217
+ */
218
+ char dir_rename_original_type;
219
+ char *dir_rename_original_dest;
220
/*
221
* Purpose of src_entry and dst_entry:
222
*
@@ -230,8 +238,6 @@ struct rename {
238
*/
239
struct stage_data *src_entry;
240
struct stage_data *dst_entry;
233
- unsigned add_turned_into_rename:1;
234
- unsigned processed:1;
241
};
242
243
struct rename_conflict_info {
@@ -2484,16 +2490,18 @@ static void apply_directory_rename_modifications(struct merge_options *opt,
2490
&re->dst_entry->stages[stage].oid,
2491
&re->dst_entry->stages[stage].mode);
2492
2487
- /* Update pair status */
2488
- if (pair->status == 'A') {
2489
- /*
2490
- * Recording rename information for this add makes it look
2491
- * like a rename/delete conflict. Make sure we can
2492
- * correctly handle this as an add that was moved to a new
2493
- * directory instead of reporting a rename/delete conflict.
2494
- */
2495
- re->add_turned_into_rename = 1;
2496
- }
2493
+ /*
2494
+ * Record the original change status (or 'type' of change). If it
2495
+ * was originally an add ('A'), this lets us differentiate later
2496
+ * between a RENAME_DELETE conflict and RENAME_VIA_DIR (they
2497
+ * otherwise look the same). If it was originally a rename ('R'),
2498
+ * this lets us remember and report accurately about the transitive
2499
+ * renaming that occurred via the directory rename detection. Also,
2500
+ * record the original destination name.
2501
+ */
2502
+ re->dir_rename_original_type = pair->status;
2503
+ re->dir_rename_original_dest = pair->two->path;
2504
+
2505
/*
2506
* We don't actually look at pair->status again, but it seems
2507
* pedagogically correct to adjust it.
@@ -2556,9 +2564,10 @@ static struct string_list *get_renames(struct merge_options *opt,
2564
2565
re = xmalloc(sizeof(*re));
2566
re->processed = 0;
2559
- re->add_turned_into_rename = 0;
2567
re->pair = pair;
2568
re->branch = branch;
2569
+ re->dir_rename_original_type = '\0';
2570
+ re->dir_rename_original_dest = NULL;
2571
item = string_list_lookup(entries, re->pair->one->path);
2572
if (!item)
2573
re->src_entry = insert_stage_data(re->pair->one->path,
@@ -2726,7 +2735,7 @@ static int process_renames(struct merge_options *opt,
2735
try_merge = 0;
2736
2737
if (oid_eq(&src_other.oid, &null_oid) &&
2729
- ren1->add_turned_into_rename) {
2738
+ ren1->dir_rename_original_type == 'A') {
2739
setup_rename_conflict_info(RENAME_VIA_DIR,
2740
opt, ren1, NULL);
2741
} else if (oid_eq(&src_other.oid, &null_oid)) {