The current union merge driver is implemented as an post process. But the xdl_merge code is quite capable to produce the result by itself. Therefore move to it there and teach git-merge-file a new --union option. Signed-off-by: Bert Wesarg <bert.wesarg@xxxxxxxxxxxxxx> --- Documentation/git-merge-file.txt | 2 +- builtin-merge-file.c | 2 + ll-merge.c | 43 ++++--------------------------------- xdiff/xdiff.h | 1 + xdiff/xmerge.c | 20 +++++++++++------ 5 files changed, 22 insertions(+), 46 deletions(-) diff --git a/Documentation/git-merge-file.txt b/Documentation/git-merge-file.txt index a5b9c1f..11dff6f 100644 --- a/Documentation/git-merge-file.txt +++ b/Documentation/git-merge-file.txt @@ -10,7 +10,7 @@ SYNOPSIS -------- [verse] 'git merge-file' [-L <current-name> [-L <base-name> [-L <other-name>]]] - [--ours|--theirs] [-p|--stdout] [-q|--quiet] [--marker-size=<n>] + [--ours|--theirs|--union] [-p|--stdout] [-q|--quiet] [--marker-size=<n>] <current-file> <base-file> <other-file> diff --git a/builtin-merge-file.c b/builtin-merge-file.c index 57d757c..f69dad6 100644 --- a/builtin-merge-file.c +++ b/builtin-merge-file.c @@ -39,6 +39,8 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix) XDL_MERGE_FAVOR_OURS), OPT_SET_INT(0, "theirs", &favor, "for conflicts, use their version", XDL_MERGE_FAVOR_THEIRS), + OPT_SET_INT(0, "union", &xmp.favor, "for conflicts, use a union version", + XDL_MERGE_FAVOR_UNION), OPT_INTEGER(0, "marker-size", &xmp.marker_size, "for conflicts, use this marker size"), OPT__QUIET(&quiet), OPT_CALLBACK('L', NULL, names, "name", diff --git a/ll-merge.c b/ll-merge.c index 4c7f11b..a4b2f4c 100644 --- a/ll-merge.c +++ b/ll-merge.c @@ -98,44 +98,11 @@ static int ll_union_merge(const struct ll_merge_driver *drv_unused, mmfile_t *src2, const char *name2, int flag, int marker_size) { - char *src, *dst; - long size; - int status, saved_style; - - /* We have to force the RCS "merge" style */ - saved_style = git_xmerge_style; - git_xmerge_style = 0; - status = ll_xdl_merge(drv_unused, result, path_unused, - orig, src1, NULL, src2, NULL, - flag, marker_size); - git_xmerge_style = saved_style; - if (status <= 0) - return status; - size = result->size; - src = dst = result->ptr; - while (size) { - char ch; - if ((marker_size < size) && - (*src == '<' || *src == '=' || *src == '>')) { - int i; - ch = *src; - for (i = 0; i < marker_size; i++) - if (src[i] != ch) - goto not_a_marker; - if (src[marker_size] != '\n') - goto not_a_marker; - src += marker_size + 1; - size -= marker_size + 1; - continue; - } - not_a_marker: - do { - ch = *src++; - *dst++ = ch; - size--; - } while (ch != '\n' && size); - } - result->size = dst - result->ptr; + /* Use union favor */ + flag = (flag & 1) | (XDL_MERGE_FAVOR_UNION << 1); + return ll_xdl_merge(drv_unused, result, path_unused, + orig, src1, NULL, src2, NULL, + flag, marker_size); return 0; } diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h index 3f6229e..22614d5 100644 --- a/xdiff/xdiff.h +++ b/xdiff/xdiff.h @@ -61,6 +61,7 @@ extern "C" { /* merge favor modes */ #define XDL_MERGE_FAVOR_OURS 1 #define XDL_MERGE_FAVOR_THEIRS 2 +#define XDL_MERGE_FAVOR_UNION 3 #define XDL_MERGE_FAVOR(flags) (((flags)>>4) & 3) #define XDL_MERGE_FLAGS(level, style, favor) ((level)|(style)|((favor)<<4)) diff --git a/xdiff/xmerge.c b/xdiff/xmerge.c index 8cbe45e..c901ecb 100644 --- a/xdiff/xmerge.c +++ b/xdiff/xmerge.c @@ -28,6 +28,7 @@ typedef struct s_xdmerge { * 0 = conflict, * 1 = no conflict, take first, * 2 = no conflict, take second. + * 3 = no conflict, take both. */ int mode; /* @@ -230,14 +231,19 @@ static int xdl_fill_merge_buffer(xdfenv_t *xe1, const char *name1, size = fill_conflict_hunk(xe1, name1, xe2, name2, size, i, style, m, dest, marker_size); - else if (m->mode == 1) - size += xdl_recs_copy(xe1, i, m->i1 + m->chg1 - i, 0, + else if (m->mode & 3) { + /* Before conflicting part */ + size += xdl_recs_copy(xe1, i, m->i1 - i, 0, dest ? dest + size : NULL); - else if (m->mode == 2) - size += xdl_recs_copy(xe2, m->i2 - m->i1 + i, - m->i1 + m->chg2 - i, 0, - dest ? dest + size : NULL); - else + /* Postimage from side #1 */ + if (m->mode & 1) + size += xdl_recs_copy(xe1, m->i1, m->chg1, 1, + dest ? dest + size : NULL); + /* Postimage from side #2 */ + if (m->mode & 2) + size += xdl_recs_copy(xe2, m->i2, m->chg2, 1, + dest ? dest + size : NULL); + } else continue; i = m->i1 + m->chg1; } -- 1.7.0.584.g2da2b -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html