diff options
author | Junio C Hamano <gitster@pobox.com> | 2021-07-17 02:42:45 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2021-07-17 02:42:45 +0200 |
commit | d3b88be1b450caa1244ed756c2fd7d7baadeafd8 (patch) | |
tree | 85d3ade6a69a5e466bf9f09dc8cbb752824d442e /merge-recursive.c | |
parent | Merge branch 'en/ort-perf-batch-13' (diff) | |
parent | merge-recursive: handle rename-to-self case (diff) | |
download | git-d3b88be1b450caa1244ed756c2fd7d7baadeafd8.tar.xz git-d3b88be1b450caa1244ed756c2fd7d7baadeafd8.zip |
Merge branch 'en/merge-dir-rename-corner-case-fix'
The merge code had funny interactions between content based rename
detection and directory rename detection.
* en/merge-dir-rename-corner-case-fix:
merge-recursive: handle rename-to-self case
merge-ort: ensure we consult df_conflict and path_conflicts
t6423: test directory renames causing rename-to-self
Diffstat (limited to 'merge-recursive.c')
-rw-r--r-- | merge-recursive.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/merge-recursive.c b/merge-recursive.c index 4327e0cfa3..9a8a39f014 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -2804,12 +2804,19 @@ static int process_renames(struct merge_options *opt, int renamed_stage = a_renames == renames1 ? 2 : 3; int other_stage = a_renames == renames1 ? 3 : 2; + /* + * Directory renames have a funny corner case... + */ + int renamed_to_self = !strcmp(ren1_src, ren1_dst); + /* BUG: We should only remove ren1_src in the base * stage and in other_stage (think of rename + * add-source case). */ - remove_file(opt, 1, ren1_src, - renamed_stage == 2 || !was_tracked(opt, ren1_src)); + if (!renamed_to_self) + remove_file(opt, 1, ren1_src, + renamed_stage == 2 || + !was_tracked(opt, ren1_src)); oidcpy(&src_other.oid, &ren1->src_entry->stages[other_stage].oid); @@ -2823,6 +2830,9 @@ static int process_renames(struct merge_options *opt, ren1->dir_rename_original_type == 'A') { setup_rename_conflict_info(RENAME_VIA_DIR, opt, ren1, NULL); + } else if (renamed_to_self) { + setup_rename_conflict_info(RENAME_NORMAL, + opt, ren1, NULL); } else if (oideq(&src_other.oid, null_oid())) { setup_rename_conflict_info(RENAME_DELETE, opt, ren1, NULL); @@ -3180,7 +3190,6 @@ static int handle_rename_normal(struct merge_options *opt, struct rename *ren = ci->ren1; struct merge_file_info mfi; int clean; - int side = (ren->branch == opt->branch1 ? 2 : 3); /* Merge the content and write it out */ clean = handle_content_merge(&mfi, opt, path, was_dirty(opt, path), @@ -3190,9 +3199,7 @@ static int handle_rename_normal(struct merge_options *opt, opt->detect_directory_renames == MERGE_DIRECTORY_RENAMES_CONFLICT && ren->dir_rename_original_dest) { if (update_stages(opt, path, - NULL, - side == 2 ? &mfi.blob : NULL, - side == 2 ? NULL : &mfi.blob)) + &mfi.blob, &mfi.blob, &mfi.blob)) return -1; clean = 0; /* not clean, but conflicted */ } |