{"thread":{"id":"22872","subject":"[PATCH 1/4] make union merge an xdl merge favor","startedAt":"2010-03-01T21:46:25Z","lastAt":"2010-03-01T21:46:28Z","messageCount":4,"participants":["Bert Wesarg"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"135980","messageId":"b34a72b5be427e4ccbdd01d7b8f53683dfd80175.1267479461.git.bert.wesarg@googlemail.com","threadId":"22872","inReplyTo":null,"subject":"[PATCH 1/4] make union merge an xdl merge favor","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-03-01T21:46:25Z","receivedAt":"2010-03-01T21:46:25Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"The current union merge driver is implemented as an post process.  But the\nxdl_merge code is quite capable to produce the result by itself.  Therefore\nmove it there.\n\nSigned-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n---\n ll-merge.c     |   43 +++++--------------------------------------\n xdiff/xdiff.h  |    1 +\n xdiff/xmerge.c |   20 +++++++++++++-------\n 3 files changed, 19 insertions(+), 45 deletions(-)\n\ndiff --git a/ll-merge.c b/ll-merge.c\nindex 4c7f11b..a4b2f4c 100644\n--- a/ll-merge.c\n+++ b/ll-merge.c\n@@ -98,44 +98,11 @@ static int ll_union_merge(const struct ll_merge_driver *drv_unused,\n \t\t\t  mmfile_t *src2, const char *name2,\n \t\t\t  int flag, int marker_size)\n {\n-\tchar *src, *dst;\n-\tlong size;\n-\tint status, saved_style;\n-\n-\t/* We have to force the RCS \"merge\" style */\n-\tsaved_style = git_xmerge_style;\n-\tgit_xmerge_style = 0;\n-\tstatus = ll_xdl_merge(drv_unused, result, path_unused,\n-\t\t\t      orig, src1, NULL, src2, NULL,\n-\t\t\t      flag, marker_size);\n-\tgit_xmerge_style = saved_style;\n-\tif (status <= 0)\n-\t\treturn status;\n-\tsize = result->size;\n-\tsrc = dst = result->ptr;\n-\twhile (size) {\n-\t\tchar ch;\n-\t\tif ((marker_size < size) &&\n-\t\t    (*src == '<' || *src == '=' || *src == '>')) {\n-\t\t\tint i;\n-\t\t\tch = *src;\n-\t\t\tfor (i = 0; i < marker_size; i++)\n-\t\t\t\tif (src[i] != ch)\n-\t\t\t\t\tgoto not_a_marker;\n-\t\t\tif (src[marker_size] != '\\n')\n-\t\t\t\tgoto not_a_marker;\n-\t\t\tsrc += marker_size + 1;\n-\t\t\tsize -= marker_size + 1;\n-\t\t\tcontinue;\n-\t\t}\n-\tnot_a_marker:\n-\t\tdo {\n-\t\t\tch = *src++;\n-\t\t\t*dst++ = ch;\n-\t\t\tsize--;\n-\t\t} while (ch != '\\n' && size);\n-\t}\n-\tresult->size = dst - result->ptr;\n+\t/* Use union favor */\n+\tflag = (flag & 1) | (XDL_MERGE_FAVOR_UNION << 1);\n+\treturn ll_xdl_merge(drv_unused, result, path_unused,\n+\t\t\t    orig, src1, NULL, src2, NULL,\n+\t\t\t    flag, marker_size);\n \treturn 0;\n }\n \ndiff --git a/xdiff/xdiff.h b/xdiff/xdiff.h\nindex 3f6229e..22614d5 100644\n--- a/xdiff/xdiff.h\n+++ b/xdiff/xdiff.h\n@@ -61,6 +61,7 @@ extern \"C\" {\n /* merge favor modes */\n #define XDL_MERGE_FAVOR_OURS 1\n #define XDL_MERGE_FAVOR_THEIRS 2\n+#define XDL_MERGE_FAVOR_UNION 3\n #define XDL_MERGE_FAVOR(flags) (((flags)>>4) & 3)\n #define XDL_MERGE_FLAGS(level, style, favor) ((level)|(style)|((favor)<<4))\n \ndiff --git a/xdiff/xmerge.c b/xdiff/xmerge.c\nindex 8cbe45e..c901ecb 100644\n--- a/xdiff/xmerge.c\n+++ b/xdiff/xmerge.c\n@@ -28,6 +28,7 @@ typedef struct s_xdmerge {\n \t * 0 = conflict,\n \t * 1 = no conflict, take first,\n \t * 2 = no conflict, take second.\n+\t * 3 = no conflict, take both.\n \t */\n \tint mode;\n \t/*\n@@ -230,14 +231,19 @@ static int xdl_fill_merge_buffer(xdfenv_t *xe1, const char *name1,\n \t\t\tsize = fill_conflict_hunk(xe1, name1, xe2, name2,\n \t\t\t\t\t\t  size, i, style, m, dest,\n \t\t\t\t\t\t  marker_size);\n-\t\telse if (m->mode == 1)\n-\t\t\tsize += xdl_recs_copy(xe1, i, m->i1 + m->chg1 - i, 0,\n+\t\telse if (m->mode & 3) {\n+\t\t\t/* Before conflicting part */\n+\t\t\tsize += xdl_recs_copy(xe1, i, m->i1 - i, 0,\n \t\t\t\t\t      dest ? dest + size : NULL);\n-\t\telse if (m->mode == 2)\n-\t\t\tsize += xdl_recs_copy(xe2, m->i2 - m->i1 + i,\n-\t\t\t\t\t      m->i1 + m->chg2 - i, 0,\n-\t\t\t\t\t      dest ? dest + size : NULL);\n-\t\telse\n+\t\t\t/* Postimage from side #1 */\n+\t\t\tif (m->mode & 1)\n+\t\t\t\tsize += xdl_recs_copy(xe1, m->i1, m->chg1, 1,\n+\t\t\t\t\t\t      dest ? dest + size : NULL);\n+\t\t\t/* Postimage from side #2 */\n+\t\t\tif (m->mode & 2)\n+\t\t\t\tsize += xdl_recs_copy(xe2, m->i2, m->chg2, 1,\n+\t\t\t\t\t\t      dest ? dest + size : NULL);\n+\t\t} else\n \t\t\tcontinue;\n \t\ti = m->i1 + m->chg1;\n \t}\n-- \n1.7.0.584.g2da2b\n"},{"id":"135982","messageId":"386850ac4b3c19e3a10ca4c6bca754487fc1adf2.1267479461.git.bert.wesarg@googlemail.com","threadId":"22872","inReplyTo":"b34a72b5be427e4ccbdd01d7b8f53683dfd80175.1267479461.git.bert.wesarg@googlemail.com","subject":"[PATCH 2/4] refactor merge flags into xmparam_t","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-03-01T21:46:26Z","receivedAt":"2010-03-01T21:46:26Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"Include the merge level, favor, and style flags into the xmparam_t struct.\nThis removes the bit twiddling with these three values into the one flags\nparameter.\n\nSigned-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n---\n builtin-merge-file.c |   18 ++++++++++--------\n ll-merge.c           |   12 ++++--------\n xdiff/xdiff.h        |   11 +++++------\n xdiff/xmerge.c       |   12 ++++++------\n 4 files changed, 25 insertions(+), 28 deletions(-)\n\ndiff --git a/builtin-merge-file.c b/builtin-merge-file.c\nindex 1e70073..3389dd0 100644\n--- a/builtin-merge-file.c\n+++ b/builtin-merge-file.c\n@@ -27,17 +27,19 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)\n \tmmbuffer_t result = {NULL, 0};\n \txmparam_t xmp = {{XDF_NEED_MINIMAL}};\n \tint ret = 0, i = 0, to_stdout = 0;\n-\tint level = XDL_MERGE_ZEALOUS_ALNUM;\n-\tint style = 0, quiet = 0;\n-\tint favor = 0;\n+\tint quiet = 0;\n \tint nongit;\n \n+\txmp.level = XDL_MERGE_ZEALOUS_ALNUM;\n+\txmp.style = 0;\n+\txmp.favor = 0;\n+\n \tstruct option options[] = {\n \t\tOPT_BOOLEAN('p', \"stdout\", &to_stdout, \"send results to standard output\"),\n-\t\tOPT_SET_INT(0, \"diff3\", &style, \"use a diff3 based merge\", XDL_MERGE_DIFF3),\n-\t\tOPT_SET_INT(0, \"ours\", &favor, \"for conflicts, use our version\",\n+\t\tOPT_SET_INT(0, \"diff3\", &xmp.style, \"use a diff3 based merge\", XDL_MERGE_DIFF3),\n+\t\tOPT_SET_INT(0, \"ours\", &xmp.favor, \"for conflicts, use our version\",\n \t\t\t    XDL_MERGE_FAVOR_OURS),\n-\t\tOPT_SET_INT(0, \"theirs\", &favor, \"for conflicts, use their version\",\n+\t\tOPT_SET_INT(0, \"theirs\", &xmp.favor, \"for conflicts, use their version\",\n \t\t\t    XDL_MERGE_FAVOR_THEIRS),\n \t\tOPT__QUIET(&quiet),\n \t\tOPT_CALLBACK('L', NULL, names, \"name\",\n@@ -50,7 +52,7 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)\n \t\t/* Read the configuration file */\n \t\tgit_config(git_xmerge_config, NULL);\n \t\tif (0 <= git_xmerge_style)\n-\t\t\tstyle = git_xmerge_style;\n+\t\t\txmp.style = git_xmerge_style;\n \t}\n \n \targc = parse_options(argc, argv, prefix, options, merge_file_usage, 0);\n@@ -73,7 +75,7 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)\n \t}\n \n \tret = xdl_merge(mmfs + 1, mmfs + 0, names[0], mmfs + 2, names[2],\n-\t\t\t&xmp, XDL_MERGE_FLAGS(level, style, favor), &result);\n+\t\t\t&xmp, &result);\n \n \tfor (i = 0; i < 3; i++)\n \t\tfree(mmfs[i].ptr);\ndiff --git a/ll-merge.c b/ll-merge.c\nindex a4b2f4c..82c7742 100644\n--- a/ll-merge.c\n+++ b/ll-merge.c\n@@ -63,8 +63,6 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,\n \t\t\tint flag, int marker_size)\n {\n \txmparam_t xmp;\n-\tint style = 0;\n-\tint favor = (flag >> 1) & 03;\n \n \tif (buffer_is_binary(orig->ptr, orig->size) ||\n \t    buffer_is_binary(src1->ptr, src1->size) ||\n@@ -79,15 +77,13 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,\n \t}\n \n \tmemset(&xmp, 0, sizeof(xmp));\n+\txmp.level = XDL_MERGE_ZEALOUS;\n+\txmp.favor= (flag >> 1) & 03;\n \tif (git_xmerge_style >= 0)\n-\t\tstyle = git_xmerge_style;\n+\t\txmp.style = git_xmerge_style;\n \tif (marker_size > 0)\n \t\txmp.marker_size = marker_size;\n-\treturn xdl_merge(orig,\n-\t\t\t src1, name1,\n-\t\t\t src2, name2,\n-\t\t\t &xmp, XDL_MERGE_FLAGS(XDL_MERGE_ZEALOUS, style, favor),\n-\t\t\t result);\n+\treturn xdl_merge(orig, src1, name1, src2, name2, &xmp, result);\n }\n \n static int ll_union_merge(const struct ll_merge_driver *drv_unused,\ndiff --git a/xdiff/xdiff.h b/xdiff/xdiff.h\nindex 22614d5..a71763a 100644\n--- a/xdiff/xdiff.h\n+++ b/xdiff/xdiff.h\n@@ -56,18 +56,14 @@ extern \"C\" {\n #define XDL_MERGE_EAGER 1\n #define XDL_MERGE_ZEALOUS 2\n #define XDL_MERGE_ZEALOUS_ALNUM 3\n-#define XDL_MERGE_LEVEL_MASK 0x0f\n \n /* merge favor modes */\n #define XDL_MERGE_FAVOR_OURS 1\n #define XDL_MERGE_FAVOR_THEIRS 2\n #define XDL_MERGE_FAVOR_UNION 3\n-#define XDL_MERGE_FAVOR(flags) (((flags)>>4) & 3)\n-#define XDL_MERGE_FLAGS(level, style, favor) ((level)|(style)|((favor)<<4))\n \n /* merge output styles */\n-#define XDL_MERGE_DIFF3 0x8000\n-#define XDL_MERGE_STYLE_MASK 0x8000\n+#define XDL_MERGE_DIFF3 1\n \n typedef struct s_mmfile {\n \tchar *ptr;\n@@ -118,13 +114,16 @@ int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,\n typedef struct s_xmparam {\n \txpparam_t xpp;\n \tint marker_size;\n+\tint level;\n+\tint favor;\n+\tint style;\n } xmparam_t;\n \n #define DEFAULT_CONFLICT_MARKER_SIZE 7\n \n int xdl_merge(mmfile_t *orig, mmfile_t *mf1, const char *name1,\n \t\tmmfile_t *mf2, const char *name2,\n-\t\txmparam_t const *xmp, int flags, mmbuffer_t *result);\n+\t\txmparam_t const *xmp, mmbuffer_t *result);\n \n #ifdef __cplusplus\n }\ndiff --git a/xdiff/xmerge.c b/xdiff/xmerge.c\nindex c901ecb..87cafa7 100644\n--- a/xdiff/xmerge.c\n+++ b/xdiff/xmerge.c\n@@ -400,13 +400,13 @@ static int xdl_simplify_non_conflicts(xdfenv_t *xe1, xdmerge_t *m,\n  */\n static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, const char *name1,\n \t\txdfenv_t *xe2, xdchange_t *xscr2, const char *name2,\n-\t\tint flags, xmparam_t const *xmp, mmbuffer_t *result) {\n+\t\txmparam_t const *xmp, mmbuffer_t *result) {\n \txdmerge_t *changes, *c;\n \txpparam_t const *xpp = &xmp->xpp;\n \tint i0, i1, i2, chg0, chg1, chg2;\n-\tint level = flags & XDL_MERGE_LEVEL_MASK;\n-\tint style = flags & XDL_MERGE_STYLE_MASK;\n-\tint favor = XDL_MERGE_FAVOR(flags);\n+\tint level = xmp->level;\n+\tint style = xmp->style;\n+\tint favor = xmp->favor;\n \n \tif (style == XDL_MERGE_DIFF3) {\n \t\t/*\n@@ -556,7 +556,7 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, const char *name1,\n \n int xdl_merge(mmfile_t *orig, mmfile_t *mf1, const char *name1,\n \t\tmmfile_t *mf2, const char *name2,\n-\t\txmparam_t const *xmp, int flags, mmbuffer_t *result) {\n+\t\txmparam_t const *xmp, mmbuffer_t *result) {\n \txdchange_t *xscr1, *xscr2;\n \txdfenv_t xe1, xe2;\n \tint status;\n@@ -593,7 +593,7 @@ int xdl_merge(mmfile_t *orig, mmfile_t *mf1, const char *name1,\n \t} else {\n \t\tstatus = xdl_do_merge(&xe1, xscr1, name1,\n \t\t\t\t      &xe2, xscr2, name2,\n-\t\t\t\t      flags, xmp, result);\n+\t\t\t\t      xmp, result);\n \t}\n \txdl_free_script(xscr1);\n \txdl_free_script(xscr2);\n-- \n1.7.0.584.g2da2b\n"},{"id":"135981","messageId":"0e7f1f44fa4a9150eb788740b70e4ad05ce2ca3b.1267479461.git.bert.wesarg@googlemail.com","threadId":"22872","inReplyTo":"b34a72b5be427e4ccbdd01d7b8f53683dfd80175.1267479461.git.bert.wesarg@googlemail.com","subject":"[RFC/PATCH 3/4] merge-file: add option to specify the marker size","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-03-01T21:46:27Z","receivedAt":"2010-03-01T21:46:27Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"This adds the abbility to specify the conflict marker size for merges outside\na git repository.\n\nSigned-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n---\n\nFor merges inside a git repository, there is a proposed idea to use a --path\nargument like git hash-object to get the marker size from git attributes.\nWhich I'm all for it. A second proposal is to give attributes as arguments to\ngit merge-file, which I suspect involves very intrusive changes.\n\nThere where also a suggestion that merge-file should support file arguments\nthat points to blob objects (ie. master:Makefile). I think the --path argument\nwould fit this usecase too.\n\nThere is also currently no sane upper bound for marker sizes. Neither in\nthe git attribute case nor in this patch.\n\n Documentation/git-merge-file.txt |    5 +++--\n builtin-merge-file.c             |    2 ++\n t/t6023-merge-file.sh            |   37 +++++++++++++++++++++++++++++++++++++\n 3 files changed, 42 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-merge-file.txt b/Documentation/git-merge-file.txt\nindex 234269a..a5b9c1f 100644\n--- a/Documentation/git-merge-file.txt\n+++ b/Documentation/git-merge-file.txt\n@@ -10,7 +10,7 @@ SYNOPSIS\n --------\n [verse]\n 'git merge-file' [-L <current-name> [-L <base-name> [-L <other-name>]]]\n-\t[--ours|--theirs] [-p|--stdout] [-q|--quiet]\n+\t[--ours|--theirs] [-p|--stdout] [-q|--quiet] [--marker-size=<n>]\n \t<current-file> <base-file> <other-file>\n \n \n@@ -37,7 +37,8 @@ normally outputs a warning and brackets the conflict with lines containing\n If there are conflicts, the user should edit the result and delete one of\n the alternatives.  When `--ours` or `--theirs` option is in effect, however,\n these conflicts are resolved favouring lines from `<current-file>` or\n-lines from `<other-file>` respectively.\n+lines from `<other-file>` respectively.  The length of the conflict markers\n+can be given with the `--marker-size` option.\n \n The exit value of this program is negative on error, and the number of\n conflicts otherwise. If the merge was clean, the exit value is 0.\ndiff --git a/builtin-merge-file.c b/builtin-merge-file.c\nindex 3389dd0..c1a35b9 100644\n--- a/builtin-merge-file.c\n+++ b/builtin-merge-file.c\n@@ -41,6 +41,8 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)\n \t\t\t    XDL_MERGE_FAVOR_OURS),\n \t\tOPT_SET_INT(0, \"theirs\", &xmp.favor, \"for conflicts, use their version\",\n \t\t\t    XDL_MERGE_FAVOR_THEIRS),\n+\t\tOPT_INTEGER(0, \"marker-size\", &xmp.marker_size,\n+\t\t\t    \"for conflicts, use this marker size\"),\n \t\tOPT__QUIET(&quiet),\n \t\tOPT_CALLBACK('L', NULL, names, \"name\",\n \t\t\t     \"set labels for file1/orig_file/file2\", &label_cb),\ndiff --git a/t/t6023-merge-file.sh b/t/t6023-merge-file.sh\nindex d605024..5034dd1 100755\n--- a/t/t6023-merge-file.sh\n+++ b/t/t6023-merge-file.sh\n@@ -215,4 +215,41 @@ test_expect_success '\"diff3 -m\" style output (2)' '\n \ttest_cmp expect actual\n '\n \n+cat >expect <<\\EOF\n+Dominus regit me,\n+<<<<<<<<<< new8.txt\n+et nihil mihi deerit;\n+\n+\n+\n+\n+In loco pascuae ibi me collocavit;\n+super aquam refectionis educavit me.\n+||||||||||\n+et nihil mihi deerit.\n+In loco pascuae ibi me collocavit,\n+super aquam refectionis educavit me;\n+==========\n+et nihil mihi deerit,\n+\n+\n+\n+\n+In loco pascuae ibi me collocavit --\n+super aquam refectionis educavit me,\n+>>>>>>>>>> new9.txt\n+animam meam convertit,\n+deduxit me super semitas jusitiae,\n+propter nomen suum.\n+Nam et si ambulavero in medio umbrae mortis,\n+non timebo mala, quoniam TU mecum es:\n+virga tua et baculus tuus ipsa me consolata sunt.\n+EOF\n+\n+test_expect_success 'marker size' '\n+\ttest_must_fail git merge-file -p --marker-size=10 \\\n+\t\tnew8.txt new5.txt new9.txt >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_done\n-- \n1.7.0.584.g2da2b\n"},{"id":"135983","messageId":"cb7b00f2ff0231ff7febe6e05bf2145e4e2fe585.1267479461.git.bert.wesarg@googlemail.com","threadId":"22872","inReplyTo":"b34a72b5be427e4ccbdd01d7b8f53683dfd80175.1267479461.git.bert.wesarg@googlemail.com","subject":"[RFC/PATCH 4/4] merge-file: add option to select union merge favor","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-03-01T21:46:28Z","receivedAt":"2010-03-01T21:46:28Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n---\n\nThe same argument as for the --marker-size apply here. For merges outside a\ngit repository, its the only way to get access to the union merge driver.\n\n Documentation/git-merge-file.txt |   13 +++++++------\n builtin-merge-file.c             |    2 ++\n 2 files changed, 9 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-merge-file.txt b/Documentation/git-merge-file.txt\nindex a5b9c1f..f334d69 100644\n--- a/Documentation/git-merge-file.txt\n+++ b/Documentation/git-merge-file.txt\n@@ -10,7 +10,7 @@ SYNOPSIS\n --------\n [verse]\n 'git merge-file' [-L <current-name> [-L <base-name> [-L <other-name>]]]\n-\t[--ours|--theirs] [-p|--stdout] [-q|--quiet] [--marker-size=<n>]\n+\t[--ours|--theirs|--union] [-p|--stdout] [-q|--quiet] [--marker-size=<n>]\n \t<current-file> <base-file> <other-file>\n \n \n@@ -35,10 +35,10 @@ normally outputs a warning and brackets the conflict with lines containing\n \t>>>>>>> B\n \n If there are conflicts, the user should edit the result and delete one of\n-the alternatives.  When `--ours` or `--theirs` option is in effect, however,\n-these conflicts are resolved favouring lines from `<current-file>` or\n-lines from `<other-file>` respectively.  The length of the conflict markers\n-can be given with the `--marker-size` option.\n+the alternatives.  When `--ours`, `--theirs`, or `--union` option is in effect,\n+however, these conflicts are resolved favouring lines from `<current-file>`,\n+lines from `<other-file>`, or lines from both respectively.  The length of the\n+conflict markers can be given with the `--marker-size` option.\n \n The exit value of this program is negative on error, and the number of\n conflicts otherwise. If the merge was clean, the exit value is 0.\n@@ -68,8 +68,9 @@ OPTIONS\n \n --ours::\n --theirs::\n+--union::\n \tInstead of leaving conflicts in the file, resolve conflicts\n-\tfavouring our (or their) side of the lines.\n+\tfavouring our (or their or both) side of the lines.\n \n \n EXAMPLES\ndiff --git a/builtin-merge-file.c b/builtin-merge-file.c\nindex c1a35b9..eaa4917 100644\n--- a/builtin-merge-file.c\n+++ b/builtin-merge-file.c\n@@ -41,6 +41,8 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)\n \t\t\t    XDL_MERGE_FAVOR_OURS),\n \t\tOPT_SET_INT(0, \"theirs\", &xmp.favor, \"for conflicts, use their version\",\n \t\t\t    XDL_MERGE_FAVOR_THEIRS),\n+\t\tOPT_SET_INT(0, \"union\", &xmp.favor, \"for conflicts, use a union version\",\n+\t\t\t    XDL_MERGE_FAVOR_UNION),\n \t\tOPT_INTEGER(0, \"marker-size\", &xmp.marker_size,\n \t\t\t    \"for conflicts, use this marker size\"),\n \t\tOPT__QUIET(&quiet),\n-- \n1.7.0.584.g2da2b\n"}]}