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>
This commit is contained in:
Elijah Newren
2019-04-05 08:00:24 -07:00
committed by Junio C Hamano
parent e0612a192a
commit 6d169fd321

View File

@ -207,8 +207,16 @@ struct stage_data {
}; };
struct rename { struct rename {
unsigned processed:1;
struct diff_filepair *pair; struct diff_filepair *pair;
const char *branch; /* branch that the rename occurred on */ const char *branch; /* branch that the rename occurred on */
/*
* If directory rename detection affected this rename, what was its
* original type ('A' or 'R') and it's original destination before
* the directory rename (otherwise, '\0' and NULL for these two vars).
*/
char dir_rename_original_type;
char *dir_rename_original_dest;
/* /*
* Purpose of src_entry and dst_entry: * Purpose of src_entry and dst_entry:
* *
@ -230,8 +238,6 @@ struct rename {
*/ */
struct stage_data *src_entry; struct stage_data *src_entry;
struct stage_data *dst_entry; struct stage_data *dst_entry;
unsigned add_turned_into_rename:1;
unsigned processed:1;
}; };
struct rename_conflict_info { struct rename_conflict_info {
@ -2484,16 +2490,18 @@ static void apply_directory_rename_modifications(struct merge_options *opt,
&re->dst_entry->stages[stage].oid, &re->dst_entry->stages[stage].oid,
&re->dst_entry->stages[stage].mode); &re->dst_entry->stages[stage].mode);
/* Update pair status */
if (pair->status == 'A') {
/* /*
* Recording rename information for this add makes it look * Record the original change status (or 'type' of change). If it
* like a rename/delete conflict. Make sure we can * was originally an add ('A'), this lets us differentiate later
* correctly handle this as an add that was moved to a new * between a RENAME_DELETE conflict and RENAME_VIA_DIR (they
* directory instead of reporting a rename/delete conflict. * otherwise look the same). If it was originally a rename ('R'),
* this lets us remember and report accurately about the transitive
* renaming that occurred via the directory rename detection. Also,
* record the original destination name.
*/ */
re->add_turned_into_rename = 1; re->dir_rename_original_type = pair->status;
} re->dir_rename_original_dest = pair->two->path;
/* /*
* We don't actually look at pair->status again, but it seems * We don't actually look at pair->status again, but it seems
* pedagogically correct to adjust it. * pedagogically correct to adjust it.
@ -2556,9 +2564,10 @@ static struct string_list *get_renames(struct merge_options *opt,
re = xmalloc(sizeof(*re)); re = xmalloc(sizeof(*re));
re->processed = 0; re->processed = 0;
re->add_turned_into_rename = 0;
re->pair = pair; re->pair = pair;
re->branch = branch; re->branch = branch;
re->dir_rename_original_type = '\0';
re->dir_rename_original_dest = NULL;
item = string_list_lookup(entries, re->pair->one->path); item = string_list_lookup(entries, re->pair->one->path);
if (!item) if (!item)
re->src_entry = insert_stage_data(re->pair->one->path, re->src_entry = insert_stage_data(re->pair->one->path,
@ -2726,7 +2735,7 @@ static int process_renames(struct merge_options *opt,
try_merge = 0; try_merge = 0;
if (oid_eq(&src_other.oid, &null_oid) && if (oid_eq(&src_other.oid, &null_oid) &&
ren1->add_turned_into_rename) { ren1->dir_rename_original_type == 'A') {
setup_rename_conflict_info(RENAME_VIA_DIR, setup_rename_conflict_info(RENAME_VIA_DIR,
opt, ren1, NULL); opt, ren1, NULL);
} else if (oid_eq(&src_other.oid, &null_oid)) { } else if (oid_eq(&src_other.oid, &null_oid)) {