Skip to content

Commit 4244ce4

Browse files
committed
xdiff: add new XDL_MERGE_FAVOR_BASE mode
Similar to XDL_MERGE_FAVOR_{OURS,THEIRS} add a new mode for favoring the base version in the event of a conflict, and add a --base flag to merge-file to allow testing this out. This will be used in a subsequent commit to reduce the prevalence of nested conflict markers which traditionally arise when using the diff3 merge.conflictStyle due to having conflicts in the virtual merge base. By eschewing using conflicted regions as the resolution for the virtual merge base, and instead preferring to use the version of the text from the merge base of the merge bases, we can avoid causing nested conflicts in the outer merge. Signed-off-by: Elijah Newren <[email protected]>
1 parent 6c0bd1f commit 4244ce4

File tree

4 files changed

+33
-2
lines changed

4 files changed

+33
-2
lines changed

builtin/merge-file.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ int cmd_merge_file(int argc,
7474
OPT_SET_INT(0, "diff3", &xmp.style, N_("use a diff3 based merge"), XDL_MERGE_DIFF3),
7575
OPT_SET_INT(0, "zdiff3", &xmp.style, N_("use a zealous diff3 based merge"),
7676
XDL_MERGE_ZEALOUS_DIFF3),
77+
OPT_SET_INT(0, "base", &xmp.favor, N_("for conflicts, use base version"),
78+
XDL_MERGE_FAVOR_BASE),
7779
OPT_SET_INT(0, "ours", &xmp.favor, N_("for conflicts, use our version"),
7880
XDL_MERGE_FAVOR_OURS),
7981
OPT_SET_INT(0, "theirs", &xmp.favor, N_("for conflicts, use their version"),

t/t6403-merge-file.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,26 @@ test_expect_success "merge conflicting with --union" '
301301
test_cmp expect.txt test.txt
302302
'
303303

304+
test_expect_success "merge conflicting with --base" '
305+
cp backup.txt test.txt &&
306+
307+
cat >expect.txt <<-\EOF &&
308+
Dominus regit me,
309+
et nihil mihi deerit.
310+
In loco pascuae ibi me collocavit,
311+
super aquam refectionis educavit me;
312+
animam meam convertit,
313+
deduxit me super semitas jusitiae,
314+
propter nomen suum.
315+
Nam et si ambulavero in medio umbrae mortis,
316+
non timebo mala, quoniam tu mecum es:
317+
virga tua et baculus tuus ipsa me consolata sunt.
318+
EOF
319+
320+
git merge-file --base test.txt orig.txt new3.txt &&
321+
test_cmp expect.txt test.txt
322+
'
323+
304324
test_expect_success "merge with conflicts, using -L" '
305325
cp backup.txt test.txt &&
306326

xdiff/xdiff.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ extern "C" {
6363
#define XDL_MERGE_FAVOR_OURS 1
6464
#define XDL_MERGE_FAVOR_THEIRS 2
6565
#define XDL_MERGE_FAVOR_UNION 3
66+
#define XDL_MERGE_FAVOR_BASE 4
6667

6768
/* merge output styles */
6869
#define XDL_MERGE_DIFF3 1

xdiff/xmerge.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ typedef struct s_xdmerge {
2626
struct s_xdmerge *next;
2727
/*
2828
* 0 = conflict,
29-
* 1 = no conflict, take first,
29+
* 1 = no conflict, take first.
3030
* 2 = no conflict, take second.
31-
* 3 = no conflict, take both.
31+
* 3 = no conflict, take both first & second.
32+
* 4 = no conflict, take base.
3233
*/
3334
int mode;
3435
/*
@@ -313,6 +314,13 @@ static int xdl_fill_merge_buffer(xdfenv_t *xe1, const char *name1,
313314
if (m->mode & 2)
314315
size += xdl_recs_copy(xe2, m->i2, m->chg2, 0, 0,
315316
dest ? dest + size : NULL);
317+
} else if (m->mode == XDL_MERGE_FAVOR_BASE) {
318+
/* Before conflicting part */
319+
size += xdl_recs_copy(xe1, i, m->i1 - i, 0, 0,
320+
dest ? dest + size : NULL);
321+
/* Image from merge base */
322+
size += xdl_orig_copy(xe1, m->i0, m->chg0, 0, 0,
323+
dest ? dest + size : NULL);
316324
} else
317325
continue;
318326
i = m->i1 + m->chg1;

0 commit comments

Comments
 (0)