summaryrefslogtreecommitdiffstats
path: root/merge-recursive.c
diff options
context:
space:
mode:
authorElijah Newren <newren@gmail.com>2018-11-07 20:40:24 -0800
committerJunio C Hamano <gitster@pobox.com>2018-11-08 14:23:53 +0900
commitb2a7942b8bcf397d9a5d3bb6671853755e14de60 (patch)
treebc05eff4994913792f1abcd745451e9e1f315ec5 /merge-recursive.c
parentb28eeb3092fd12e24485fbadebfa57df457dd09a (diff)
downloadgit-b2a7942b8bcf397d9a5d3bb6671853755e14de60.tar.gz
git-b2a7942b8bcf397d9a5d3bb6671853755e14de60.tar.xz
merge-recursive: increase marker length with depth of recursion
Later patches in this series will modify file collision conflict handling (e.g. from rename/add and rename/rename(2to1) conflicts) so that multiply nested conflict markers can arise even before considering conflicts in the virtual merge base. Including the virtual merge base will provide a way to get triply (or higher) nested conflict markers. This new way to get nested conflict markers will force the need for a more general mechanism to extend the length of conflict markers in order to differentiate between different nestings. Along with this change to conflict marker length handling, we want to make sure that we don't regress handling for other types of conflicts with nested conflict markers. Add a more involved testcase using merge.conflictstyle=diff3, where not only does the virtual merge base contain conflicts, but its virtual merge base does as well (i.e. a case with triply nested conflict markers). While there are multiple reasonable ways to handle nested conflict markers in the virtual merge base for this type of situation, the easiest approach that dovetails well with the new needs for the file collision conflict handling is to require that the length of the conflict markers increase with each subsequent nesting. Subsequent patches which change the rename/add and rename/rename(2to1) conflict handling will modify the extra_marker_size flag appropriately for their new needs. 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.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/merge-recursive.c b/merge-recursive.c
index 73b571038..f795c92a6 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -1058,7 +1058,8 @@ static int merge_3way(struct merge_options *o,
const struct diff_filespec *a,
const struct diff_filespec *b,
const char *branch1,
- const char *branch2)
+ const char *branch2,
+ const int extra_marker_size)
{
mmfile_t orig, src1, src2;
struct ll_merge_options ll_opts = {0};
@@ -1066,6 +1067,7 @@ static int merge_3way(struct merge_options *o,
int merge_status;
ll_opts.renormalize = o->renormalize;
+ ll_opts.extra_marker_size = extra_marker_size;
ll_opts.xdl_opts = o->xdl_opts;
if (o->call_depth) {
@@ -1300,6 +1302,7 @@ static int merge_mode_and_contents(struct merge_options *o,
const char *filename,
const char *branch1,
const char *branch2,
+ const int extra_marker_size,
struct merge_file_info *result)
{
if (o->branch1 != branch1) {
@@ -1310,7 +1313,8 @@ static int merge_mode_and_contents(struct merge_options *o,
*/
return merge_mode_and_contents(o, one, b, a,
filename,
- branch2, branch1, result);
+ branch2, branch1,
+ extra_marker_size, result);
}
result->merge = 0;
@@ -1351,7 +1355,8 @@ static int merge_mode_and_contents(struct merge_options *o,
int ret = 0, merge_status;
merge_status = merge_3way(o, &result_buf, one, a, b,
- branch1, branch2);
+ branch1, branch2,
+ extra_marker_size);
if ((merge_status < 0) || !result_buf.ptr)
ret = err(o, _("Failed to execute internal merge"));
@@ -1640,7 +1645,8 @@ static int handle_rename_rename_1to2(struct merge_options *o,
struct diff_filespec other;
struct diff_filespec *add;
if (merge_mode_and_contents(o, one, a, b, one->path,
- ci->branch1, ci->branch2, &mfi))
+ ci->branch1, ci->branch2,
+ o->call_depth * 2, &mfi))
return -1;
/*
@@ -1707,9 +1713,11 @@ static int handle_rename_rename_2to1(struct merge_options *o,
path_side_1_desc = xstrfmt("version of %s from %s", path, a->path);
path_side_2_desc = xstrfmt("version of %s from %s", path, b->path);
if (merge_mode_and_contents(o, a, c1, &ci->ren1_other, path_side_1_desc,
- o->branch1, o->branch2, &mfi_c1) ||
+ o->branch1, o->branch2,
+ o->call_depth * 2, &mfi_c1) ||
merge_mode_and_contents(o, b, &ci->ren2_other, c2, path_side_2_desc,
- o->branch1, o->branch2, &mfi_c2))
+ o->branch1, o->branch2,
+ o->call_depth * 2, &mfi_c2))
return -1;
free(path_side_1_desc);
free(path_side_2_desc);
@@ -2755,7 +2763,7 @@ static int process_renames(struct merge_options *o,
if (merge_mode_and_contents(o, &one, &a, &b, ren1_dst,
branch1, branch2,
- &mfi)) {
+ o->call_depth * 2, &mfi)) {
clean_merge = -1;
goto cleanup_and_return;
}
@@ -3052,7 +3060,8 @@ static int handle_content_merge(struct merge_options *o,
df_conflict_remains = 1;
}
if (merge_mode_and_contents(o, &one, &a, &b, path,
- o->branch1, o->branch2, &mfi))
+ o->branch1, o->branch2,
+ o->call_depth * 2, &mfi))
return -1;
/*