diff options
author | Elijah Newren <newren@gmail.com> | 2020-02-27 03:05:05 +0300 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2020-02-27 21:59:59 +0300 |
commit | 802050400a51270bd2b4a13e410412693975c766 (patch) | |
tree | d9e2b0722a9f17e9bc8de654065388f22c954554 /merge-recursive.c | |
parent | 2d2118b814c11f509e1aa76cb07110f7231668dc (diff) |
merge-recursive: apply collision handling unification to recursive case
In the en/merge-path-collision topic (see commit ac193e0e0aa5, "Merge
branch 'en/merge-path-collision'", 2019-01-04), all the "file collision"
conflict types were modified for consistency. In particular,
rename/add, rename/rename(2to1) and each rename/add piece of a
rename/rename(1to2)/add[/add] conflict were made to behave like add/add
conflicts have always been handled.
However, this consistency was not enforced when opt->priv->call_depth >
0 for rename/rename conflicts. Update rename/rename(1to2) and
rename/rename(2to1) conflicts in the recursive case to also be
consistent. As an added bonus, this simplifies the code considerably.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'merge-recursive.c')
-rw-r--r-- | merge-recursive.c | 152 |
1 files changed, 47 insertions, 105 deletions
diff --git a/merge-recursive.c b/merge-recursive.c index aee1769a7a..3728b3f659 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -1557,35 +1557,6 @@ static int handle_file_collision(struct merge_options *opt, b, a); } - /* - * In the recursive case, we just opt to undo renames - */ - if (opt->priv->call_depth && (prev_path1 || prev_path2)) { - /* Put first file (a->oid, a->mode) in its original spot */ - if (prev_path1) { - if (update_file(opt, 1, a, prev_path1)) - return -1; - } else { - if (update_file(opt, 1, a, collide_path)) - return -1; - } - - /* Put second file (b->oid, b->mode) in its original spot */ - if (prev_path2) { - if (update_file(opt, 1, b, prev_path2)) - return -1; - } else { - if (update_file(opt, 1, b, collide_path)) - return -1; - } - - /* Don't leave something at collision path if unrenaming both */ - if (prev_path1 && prev_path2) - remove_file(opt, 1, collide_path, 0); - - return 0; - } - /* Remove rename sources if rename/add or rename/rename(2to1) */ if (prev_path1) remove_file(opt, 1, prev_path1, @@ -1746,85 +1717,56 @@ static int handle_rename_rename_1to2(struct merge_options *opt, return -1; free(path_desc); - if (opt->priv->call_depth) { - /* - * FIXME: For rename/add-source conflicts (if we could detect - * such), this is wrong. We should instead find a unique - * pathname and then either rename the add-source file to that - * unique path, or use that unique path instead of src here. - */ - if (update_file(opt, 0, &mfi.blob, o->path)) - return -1; + if (opt->priv->call_depth) + remove_file_from_index(opt->repo->index, o->path); - /* - * Above, we put the merged content at the merge-base's - * path. Now we usually need to delete both a->path and - * b->path. However, the rename on each side of the merge - * could also be involved in a rename/add conflict. In - * such cases, we should keep the added file around, - * resolving the conflict at that path in its favor. - */ - add = &ci->ren1->dst_entry->stages[flip_stage(2)]; - if (is_valid(add)) { - if (update_file(opt, 0, add, a->path)) - return -1; - } - else - remove_file_from_index(opt->repo->index, a->path); - add = &ci->ren2->dst_entry->stages[flip_stage(3)]; - if (is_valid(add)) { - if (update_file(opt, 0, add, b->path)) - return -1; - } - else - remove_file_from_index(opt->repo->index, b->path); + /* + * For each destination path, we need to see if there is a + * rename/add collision. If not, we can write the file out + * to the specified location. + */ + add = &ci->ren1->dst_entry->stages[flip_stage(2)]; + if (is_valid(add)) { + add->path = mfi.blob.path = a->path; + if (handle_file_collision(opt, a->path, + NULL, NULL, + ci->ren1->branch, + ci->ren2->branch, + &mfi.blob, add) < 0) + return -1; } else { - /* - * For each destination path, we need to see if there is a - * rename/add collision. If not, we can write the file out - * to the specified location. - */ - add = &ci->ren1->dst_entry->stages[flip_stage(2)]; - if (is_valid(add)) { - add->path = mfi.blob.path = a->path; - if (handle_file_collision(opt, a->path, - NULL, NULL, - ci->ren1->branch, - ci->ren2->branch, - &mfi.blob, add) < 0) - return -1; - } else { - char *new_path = find_path_for_conflict(opt, a->path, - ci->ren1->branch, - ci->ren2->branch); - if (update_file(opt, 0, &mfi.blob, - new_path ? new_path : a->path)) - return -1; - free(new_path); - if (update_stages(opt, a->path, NULL, a, NULL)) - return -1; - } + char *new_path = find_path_for_conflict(opt, a->path, + ci->ren1->branch, + ci->ren2->branch); + if (update_file(opt, 0, &mfi.blob, + new_path ? new_path : a->path)) + return -1; + free(new_path); + if (!opt->priv->call_depth && + update_stages(opt, a->path, NULL, a, NULL)) + return -1; + } - add = &ci->ren2->dst_entry->stages[flip_stage(3)]; - if (is_valid(add)) { - add->path = mfi.blob.path = b->path; - if (handle_file_collision(opt, b->path, - NULL, NULL, - ci->ren1->branch, - ci->ren2->branch, - add, &mfi.blob) < 0) - return -1; - } else { - char *new_path = find_path_for_conflict(opt, b->path, - ci->ren2->branch, - ci->ren1->branch); - if (update_file(opt, 0, &mfi.blob, - new_path ? new_path : b->path)) - return -1; - free(new_path); - if (update_stages(opt, b->path, NULL, NULL, b)) - return -1; - } + add = &ci->ren2->dst_entry->stages[flip_stage(3)]; + if (is_valid(add)) { + add->path = mfi.blob.path = b->path; + if (handle_file_collision(opt, b->path, + NULL, NULL, + ci->ren1->branch, + ci->ren2->branch, + add, &mfi.blob) < 0) + return -1; + } else { + char *new_path = find_path_for_conflict(opt, b->path, + ci->ren2->branch, + ci->ren1->branch); + if (update_file(opt, 0, &mfi.blob, + new_path ? new_path : b->path)) + return -1; + free(new_path); + if (!opt->priv->call_depth && + update_stages(opt, b->path, NULL, NULL, b)) + return -1; } return 0; |