From: Junio C Hamano Date: Thu, 21 Jan 2010 04:28:51 +0000 (-0800) Subject: Merge branch 'jc/conflict-marker-size' X-Git-Tag: v1.7.0-rc0~53 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/06dbc1ea5768618337bf11e5f64c4f9f14a68008?ds=inline;hp=-c Merge branch 'jc/conflict-marker-size' * jc/conflict-marker-size: rerere: honor conflict-marker-size attribute rerere: prepare for customizable conflict marker length conflict-marker-size: new attribute rerere: use ll_merge() instead of using xdl_merge() merge-tree: use ll_merge() not xdl_merge() xdl_merge(): allow passing down marker_size in xmparam_t xdl_merge(): introduce xmparam_t for merge specific parameters git_attr(): fix function signature Conflicts: builtin-merge-file.c ll-merge.c xdiff/xdiff.h xdiff/xmerge.c --- 06dbc1ea5768618337bf11e5f64c4f9f14a68008 diff --combined archive.c index 5b88507374,a9ebdc5d54..d700af3b62 --- a/archive.c +++ b/archive.c @@@ -87,8 -87,8 +87,8 @@@ static void setup_archive_check(struct static struct git_attr *attr_export_subst; if (!attr_export_ignore) { - attr_export_ignore = git_attr("export-ignore", 13); - attr_export_subst = git_attr("export-subst", 12); + attr_export_ignore = git_attr("export-ignore"); + attr_export_subst = git_attr("export-subst"); } check[0].attr = attr_export_ignore; check[1].attr = attr_export_subst; @@@ -211,33 -211,10 +211,33 @@@ static const struct archiver *lookup_ar return NULL; } +static int reject_entry(const unsigned char *sha1, const char *base, + int baselen, const char *filename, unsigned mode, + int stage, void *context) +{ + return -1; +} + +static int path_exists(struct tree *tree, const char *path) +{ + const char *pathspec[] = { path, NULL }; + + if (read_tree_recursive(tree, "", 0, 0, pathspec, reject_entry, NULL)) + return 1; + return 0; +} + static void parse_pathspec_arg(const char **pathspec, struct archiver_args *ar_args) { - ar_args->pathspec = get_pathspec("", pathspec); + ar_args->pathspec = pathspec = get_pathspec("", pathspec); + if (pathspec) { + while (*pathspec) { + if (!path_exists(ar_args->tree, *pathspec)) + die("path not found: %s", *pathspec); + pathspec++; + } + } } static void parse_treeish_arg(const char **argv, diff --combined builtin-merge-file.c index 1efc4e09bc,11c3524a77..1e70073a7e --- a/builtin-merge-file.c +++ b/builtin-merge-file.c @@@ -25,20 -25,15 +25,20 @@@ int cmd_merge_file(int argc, const cha const char *names[3] = { NULL, NULL, NULL }; mmfile_t mmfs[3]; mmbuffer_t result = {NULL, 0}; - xpparam_t xpp = {XDF_NEED_MINIMAL}; + xmparam_t xmp = {{XDF_NEED_MINIMAL}}; int ret = 0, i = 0, to_stdout = 0; - int merge_level = XDL_MERGE_ZEALOUS_ALNUM; - int merge_style = 0, quiet = 0; + int level = XDL_MERGE_ZEALOUS_ALNUM; + int style = 0, quiet = 0; + int favor = 0; int nongit; struct option options[] = { OPT_BOOLEAN('p', "stdout", &to_stdout, "send results to standard output"), - OPT_SET_INT(0, "diff3", &merge_style, "use a diff3 based merge", XDL_MERGE_DIFF3), + OPT_SET_INT(0, "diff3", &style, "use a diff3 based merge", XDL_MERGE_DIFF3), + OPT_SET_INT(0, "ours", &favor, "for conflicts, use our version", + XDL_MERGE_FAVOR_OURS), + OPT_SET_INT(0, "theirs", &favor, "for conflicts, use their version", + XDL_MERGE_FAVOR_THEIRS), OPT__QUIET(&quiet), OPT_CALLBACK('L', NULL, names, "name", "set labels for file1/orig_file/file2", &label_cb), @@@ -50,7 -45,7 +50,7 @@@ /* Read the configuration file */ git_config(git_xmerge_config, NULL); if (0 <= git_xmerge_style) - merge_style = git_xmerge_style; + style = git_xmerge_style; } argc = parse_options(argc, argv, prefix, options, merge_file_usage, 0); @@@ -73,7 -68,7 +73,7 @@@ } ret = xdl_merge(mmfs + 1, mmfs + 0, names[0], mmfs + 2, names[2], - &xpp, XDL_MERGE_FLAGS(level, style, favor), &result); - &xmp, merge_level | merge_style, &result); ++ &xmp, XDL_MERGE_FLAGS(level, style, favor), &result); for (i = 0; i < 3; i++) free(mmfs[i].ptr); diff --combined builtin-pack-objects.c index 890f45cf20,9beff352d5..59b07fe491 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@@ -673,7 -673,7 +673,7 @@@ static void setup_delta_attr_check(stru static struct git_attr *attr_delta; if (!attr_delta) - attr_delta = git_attr("delta", 5); + attr_delta = git_attr("delta"); check[0].attr = attr_delta; } @@@ -1256,15 -1256,15 +1256,15 @@@ static int delta_cacheable(unsigned lon #ifdef THREADED_DELTA_SEARCH -static pthread_mutex_t read_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t read_mutex; #define read_lock() pthread_mutex_lock(&read_mutex) #define read_unlock() pthread_mutex_unlock(&read_mutex) -static pthread_mutex_t cache_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t cache_mutex; #define cache_lock() pthread_mutex_lock(&cache_mutex) #define cache_unlock() pthread_mutex_unlock(&cache_mutex) -static pthread_mutex_t progress_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t progress_mutex; #define progress_lock() pthread_mutex_lock(&progress_mutex) #define progress_unlock() pthread_mutex_unlock(&progress_mutex) @@@ -1591,26 -1591,7 +1591,26 @@@ struct thread_params unsigned *processed; }; -static pthread_cond_t progress_cond = PTHREAD_COND_INITIALIZER; +static pthread_cond_t progress_cond; + +/* + * Mutex and conditional variable can't be statically-initialized on Windows. + */ +static void init_threaded_search(void) +{ + pthread_mutex_init(&read_mutex, NULL); + pthread_mutex_init(&cache_mutex, NULL); + pthread_mutex_init(&progress_mutex, NULL); + pthread_cond_init(&progress_cond, NULL); +} + +static void cleanup_threaded_search(void) +{ + pthread_cond_destroy(&progress_cond); + pthread_mutex_destroy(&read_mutex); + pthread_mutex_destroy(&cache_mutex); + pthread_mutex_destroy(&progress_mutex); +} static void *threaded_find_deltas(void *arg) { @@@ -1649,13 -1630,10 +1649,13 @@@ static void ll_find_deltas(struct objec struct thread_params *p; int i, ret, active_threads = 0; + init_threaded_search(); + if (!delta_search_threads) /* --threads=0 means autodetect */ delta_search_threads = online_cpus(); if (delta_search_threads <= 1) { find_deltas(list, &list_size, window, depth, processed); + cleanup_threaded_search(); return; } if (progress > pack_to_stdout) @@@ -1770,7 -1748,6 +1770,7 @@@ active_threads--; } } + cleanup_threaded_search(); free(p); } diff --combined convert.c index 950b1f9840,852fd6488a..27acce58bc --- a/convert.c +++ b/convert.c @@@ -249,11 -249,10 +249,11 @@@ static int filter_buffer(int fd, void * struct child_process child_process; struct filter_params *params = (struct filter_params *)data; int write_err, status; - const char *argv[] = { "sh", "-c", params->cmd, NULL }; + const char *argv[] = { params->cmd, NULL }; memset(&child_process, 0, sizeof(child_process)); child_process.argv = argv; + child_process.use_shell = 1; child_process.in = -1; child_process.out = fd; @@@ -378,9 -377,9 +378,9 @@@ static void setup_convert_check(struct static struct git_attr *attr_filter; if (!attr_crlf) { - attr_crlf = git_attr("crlf", 4); - attr_ident = git_attr("ident", 5); - attr_filter = git_attr("filter", 6); + attr_crlf = git_attr("crlf"); + attr_ident = git_attr("ident"); + attr_filter = git_attr("filter"); user_convert_tail = &user_convert; git_config(read_convert_config, NULL); } diff --combined ll-merge.c index 070d66dd40,0dcaae0dd1..4c7f11ba84 --- a/ll-merge.c +++ b/ll-merge.c @@@ -18,7 -18,8 +18,8 @@@ typedef int (*ll_merge_fn)(const struc mmfile_t *orig, mmfile_t *src1, const char *name1, mmfile_t *src2, const char *name2, - int flag); - int virtual_ancestor, ++ int flag, + int marker_size); struct ll_merge_driver { const char *name; @@@ -38,14 -39,14 +39,14 @@@ static int ll_binary_merge(const struc mmfile_t *orig, mmfile_t *src1, const char *name1, mmfile_t *src2, const char *name2, - int flag) - int virtual_ancestor, int marker_size) ++ int flag, int marker_size) { /* * The tentative merge result is "ours" for the final round, * or common ancestor for an internal merge. Still return * "conflicted merge" status. */ - mmfile_t *stolen = virtual_ancestor ? orig : src1; + mmfile_t *stolen = (flag & 01) ? orig : src1; result->ptr = stolen->ptr; result->size = stolen->size; @@@ -59,11 -60,10 +60,11 @@@ static int ll_xdl_merge(const struct ll mmfile_t *orig, mmfile_t *src1, const char *name1, mmfile_t *src2, const char *name2, - int flag) - int virtual_ancestor, int marker_size) ++ int flag, int marker_size) { - xpparam_t xpp; + xmparam_t xmp; int style = 0; + int favor = (flag >> 1) & 03; if (buffer_is_binary(orig->ptr, orig->size) || buffer_is_binary(src1->ptr, src1->size) || @@@ -73,16 -73,19 +74,19 @@@ return ll_binary_merge(drv_unused, result, path, orig, src1, name1, - src2, name2, flag); + src2, name2, - virtual_ancestor, marker_size); ++ flag, marker_size); } - memset(&xpp, 0, sizeof(xpp)); + memset(&xmp, 0, sizeof(xmp)); if (git_xmerge_style >= 0) style = git_xmerge_style; + if (marker_size > 0) + xmp.marker_size = marker_size; return xdl_merge(orig, src1, name1, src2, name2, - &xpp, XDL_MERGE_FLAGS(XDL_MERGE_ZEALOUS, style, favor), - &xmp, XDL_MERGE_ZEALOUS | style, ++ &xmp, XDL_MERGE_FLAGS(XDL_MERGE_ZEALOUS, style, favor), result); } @@@ -92,11 -95,10 +96,10 @@@ static int ll_union_merge(const struct mmfile_t *orig, mmfile_t *src1, const char *name1, mmfile_t *src2, const char *name2, - int flag) - int virtual_ancestor, int marker_size) ++ int flag, int marker_size) { char *src, *dst; long size; - const int marker_size = 7; int status, saved_style; /* We have to force the RCS "merge" style */ @@@ -104,7 -106,7 +107,7 @@@ git_xmerge_style = 0; status = ll_xdl_merge(drv_unused, result, path_unused, orig, src1, NULL, src2, NULL, - flag); - virtual_ancestor, marker_size); ++ flag, marker_size); git_xmerge_style = saved_style; if (status <= 0) return status; @@@ -165,17 -167,18 +168,18 @@@ static int ll_ext_merge(const struct ll mmfile_t *orig, mmfile_t *src1, const char *name1, mmfile_t *src2, const char *name2, - int flag) - int virtual_ancestor, int marker_size) ++ int flag, int marker_size) { - char temp[3][50]; + char temp[4][50]; struct strbuf cmd = STRBUF_INIT; struct strbuf_expand_dict_entry dict[] = { { "O", temp[0] }, { "A", temp[1] }, { "B", temp[2] }, + { "L", temp[3] }, { NULL } }; - const char *args[] = { "sh", "-c", NULL, NULL }; + const char *args[] = { NULL, NULL }; int status, fd, i; struct stat st; @@@ -187,11 -190,12 +191,12 @@@ create_temp(orig, temp[0]); create_temp(src1, temp[1]); create_temp(src2, temp[2]); + sprintf(temp[3], "%d", marker_size); strbuf_expand(&cmd, fn->cmdline, strbuf_expand_dict_cb, &dict); - args[2] = cmd.buf; - status = run_command_v_opt(args, 0); + args[0] = cmd.buf; + status = run_command_v_opt(args, RUN_USING_SHELL); fd = open(temp[1], O_RDONLY); if (fd < 0) goto bad; @@@ -279,6 -283,7 +284,7 @@@ static int read_merge_config(const cha * %O - temporary file name for the merge base. * %A - temporary file name for our version. * %B - temporary file name for the other branches' version. + * %L - conflict marker length * * The external merge driver should write the results in the * file named by %A, and signal that it has done with zero exit @@@ -339,16 -344,13 +345,13 @@@ static const struct ll_merge_driver *fi return &ll_merge_drv[LL_TEXT_MERGE]; } - static const char *git_path_check_merge(const char *path) + static int git_path_check_merge(const char *path, struct git_attr_check check[2]) { - static struct git_attr_check attr_merge_check; - - if (!attr_merge_check.attr) - attr_merge_check.attr = git_attr("merge", 5); - - if (git_checkattr(path, 1, &attr_merge_check)) - return NULL; - return attr_merge_check.value; + if (!check[0].attr) { + check[0].attr = git_attr("merge"); + check[1].attr = git_attr("conflict-marker-size"); + } + return git_checkattr(path, 2, check); } int ll_merge(mmbuffer_t *result_buf, @@@ -356,19 -358,40 +359,41 @@@ mmfile_t *ancestor, mmfile_t *ours, const char *our_label, mmfile_t *theirs, const char *their_label, - int virtual_ancestor) + int flag) { - const char *ll_driver_name; + static struct git_attr_check check[2]; + const char *ll_driver_name = NULL; + int marker_size = DEFAULT_CONFLICT_MARKER_SIZE; const struct ll_merge_driver *driver; + int virtual_ancestor = flag & 01; - ll_driver_name = git_path_check_merge(path); + if (!git_path_check_merge(path, check)) { + ll_driver_name = check[0].value; + if (check[1].value) { + marker_size = atoi(check[1].value); + if (marker_size <= 0) + marker_size = DEFAULT_CONFLICT_MARKER_SIZE; + } + } driver = find_ll_merge_driver(ll_driver_name); - if (virtual_ancestor && driver->recursive) driver = find_ll_merge_driver(driver->recursive); - return driver->fn(driver, result_buf, path, - ancestor, - ours, our_label, - theirs, their_label, flag); + return driver->fn(driver, result_buf, path, ancestor, + ours, our_label, theirs, their_label, - virtual_ancestor, marker_size); ++ flag, marker_size); + } + + int ll_merge_marker_size(const char *path) + { + static struct git_attr_check check; + int marker_size = DEFAULT_CONFLICT_MARKER_SIZE; + + if (!check.attr) + check.attr = git_attr("conflict-marker-size"); + if (!git_checkattr(path, 1, &check) && check.value) { + marker_size = atoi(check.value); + if (marker_size <= 0) + marker_size = DEFAULT_CONFLICT_MARKER_SIZE; + } + return marker_size; } diff --combined ll-merge.h index aaed46dec9,ff5d84a345..57889227b1 --- a/ll-merge.h +++ b/ll-merge.h @@@ -10,6 -10,8 +10,8 @@@ int ll_merge(mmbuffer_t *result_buf mmfile_t *ancestor, mmfile_t *ours, const char *our_label, mmfile_t *theirs, const char *their_label, - int virtual_ancestor); + int flag); + int ll_merge_marker_size(const char *path); + #endif diff --combined rerere.c index 70d0f7afff,b988b467fa..a86d73d9dc --- a/rerere.c +++ b/rerere.c @@@ -1,11 -1,11 +1,11 @@@ #include "cache.h" #include "string-list.h" #include "rerere.h" - #include "xdiff/xdiff.h" #include "xdiff-interface.h" #include "dir.h" #include "resolve-undo.h" #include "ll-merge.h" + #include "attr.h" /* if rerere_enabled == -1, fall back to detection of .git/rr-cache */ static int rerere_enabled = -1; @@@ -99,6 -99,28 +99,28 @@@ static void rerere_io_putstr(const cha ferr_puts(str, io->output, &io->wrerror); } + static void rerere_io_putconflict(int ch, int size, struct rerere_io *io) + { + char buf[64]; + + while (size) { + if (size < sizeof(buf) - 2) { + memset(buf, ch, size); + buf[size] = '\n'; + buf[size + 1] = '\0'; + size = 0; + } else { + int sz = sizeof(buf) - 1; + if (size <= sz) + sz -= (sz - size) + 1; + memset(buf, ch, sz); + buf[sz] = '\0'; + size -= sz; + } + rerere_io_putstr(buf, io); + } + } + static void rerere_io_putmem(const char *mem, size_t sz, struct rerere_io *io) { if (io->output) @@@ -116,7 -138,17 +138,17 @@@ static int rerere_file_getline(struct s return strbuf_getwholeline(sb, io->input, '\n'); } - static int handle_path(unsigned char *sha1, struct rerere_io *io) + static int is_cmarker(char *buf, int marker_char, int marker_size, int want_sp) + { + while (marker_size--) + if (*buf++ != marker_char) + return 0; + if (want_sp && *buf != ' ') + return 0; + return isspace(*buf); + } + + static int handle_path(unsigned char *sha1, struct rerere_io *io, int marker_size) { git_SHA_CTX ctx; int hunk_no = 0; @@@ -130,30 -162,30 +162,30 @@@ git_SHA1_Init(&ctx); while (!io->getline(&buf, io)) { - if (!prefixcmp(buf.buf, "<<<<<<< ")) { + if (is_cmarker(buf.buf, '<', marker_size, 1)) { if (hunk != RR_CONTEXT) goto bad; hunk = RR_SIDE_1; - } else if (!prefixcmp(buf.buf, "|||||||") && isspace(buf.buf[7])) { + } else if (is_cmarker(buf.buf, '|', marker_size, 0)) { if (hunk != RR_SIDE_1) goto bad; hunk = RR_ORIGINAL; - } else if (!prefixcmp(buf.buf, "=======") && isspace(buf.buf[7])) { + } else if (is_cmarker(buf.buf, '=', marker_size, 0)) { if (hunk != RR_SIDE_1 && hunk != RR_ORIGINAL) goto bad; hunk = RR_SIDE_2; - } else if (!prefixcmp(buf.buf, ">>>>>>> ")) { + } else if (is_cmarker(buf.buf, '>', marker_size, 1)) { if (hunk != RR_SIDE_2) goto bad; if (strbuf_cmp(&one, &two) > 0) strbuf_swap(&one, &two); hunk_no++; hunk = RR_CONTEXT; - rerere_io_putstr("<<<<<<<\n", io); + rerere_io_putconflict('<', marker_size, io); rerere_io_putmem(one.buf, one.len, io); - rerere_io_putstr("=======\n", io); + rerere_io_putconflict('=', marker_size, io); rerere_io_putmem(two.buf, two.len, io); - rerere_io_putstr(">>>>>>>\n", io); + rerere_io_putconflict('>', marker_size, io); if (sha1) { git_SHA1_Update(&ctx, one.buf ? one.buf : "", one.len + 1); @@@ -190,6 -222,7 +222,7 @@@ static int handle_file(const char *path { int hunk_no = 0; struct rerere_io_file io; + int marker_size = ll_merge_marker_size(path); memset(&io, 0, sizeof(io)); io.io.getline = rerere_file_getline; @@@ -206,7 -239,7 +239,7 @@@ } } - hunk_no = handle_path(sha1, (struct rerere_io *)&io); + hunk_no = handle_path(sha1, (struct rerere_io *)&io, marker_size); fclose(io.input); if (io.io.wrerror) @@@ -256,6 -289,7 +289,7 @@@ static int handle_cache(const char *pat struct cache_entry *ce; int pos, len, i, hunk_no; struct rerere_io_mem io; + int marker_size = ll_merge_marker_size(path); /* * Reproduce the conflicted merge in-core @@@ -300,7 -334,7 +334,7 @@@ strbuf_init(&io.input, 0); strbuf_attach(&io.input, result.ptr, result.size, result.size); - hunk_no = handle_path(sha1, (struct rerere_io *)&io); + hunk_no = handle_path(sha1, (struct rerere_io *)&io, marker_size); strbuf_release(&io.input); if (io.io.output) fclose(io.io.output); @@@ -332,7 -366,6 +366,6 @@@ static int merge(const char *name, cons int ret; mmfile_t cur, base, other; mmbuffer_t result = {NULL, 0}; - xpparam_t xpp = {XDF_NEED_MINIMAL}; if (handle_file(path, NULL, rerere_path(name, "thisimage")) < 0) return 1; @@@ -341,8 -374,7 +374,7 @@@ read_mmfile(&base, rerere_path(name, "preimage")) || read_mmfile(&other, rerere_path(name, "postimage"))) return 1; - ret = xdl_merge(&base, &cur, "", &other, "", - &xpp, XDL_MERGE_ZEALOUS, &result); + ret = ll_merge(&result, path, &base, &cur, "", &other, "", 0); if (!ret) { FILE *f = fopen(path, "w"); if (!f) @@@ -493,7 -525,7 +525,7 @@@ static int is_rerere_enabled(void return 1; } -int setup_rerere(struct string_list *merge_rr) +int setup_rerere(struct string_list *merge_rr, int flags) { int fd; @@@ -501,8 -533,6 +533,8 @@@ if (!is_rerere_enabled()) return -1; + if (flags & (RERERE_AUTOUPDATE|RERERE_NOAUTOUPDATE)) + rerere_autoupdate = !!(flags & RERERE_AUTOUPDATE); merge_rr_path = git_pathdup("MERGE_RR"); fd = hold_lock_file_for_update(&write_lock, merge_rr_path, LOCK_DIE_ON_ERROR); @@@ -510,12 -540,12 +542,12 @@@ return fd; } -int rerere(void) +int rerere(int flags) { struct string_list merge_rr = { NULL, 0, 0, 1 }; int fd; - fd = setup_rerere(&merge_rr); + fd = setup_rerere(&merge_rr, flags); if (fd < 0) return 0; return do_plain_rerere(&merge_rr, fd); @@@ -556,7 -586,7 +588,7 @@@ int rerere_forget(const char **pathspec if (read_cache() < 0) return error("Could not read index"); - fd = setup_rerere(&merge_rr); + fd = setup_rerere(&merge_rr, RERERE_NOAUTOUPDATE); unmerge_cache(pathspec); find_conflict(&conflict); diff --combined xdiff/xdiff.h index 8a0efed313,22f3913427..3f6229edbe --- a/xdiff/xdiff.h +++ b/xdiff/xdiff.h @@@ -58,12 -58,6 +58,12 @@@ extern "C" #define XDL_MERGE_ZEALOUS_ALNUM 3 #define XDL_MERGE_LEVEL_MASK 0x0f +/* merge favor modes */ +#define XDL_MERGE_FAVOR_OURS 1 +#define XDL_MERGE_FAVOR_THEIRS 2 +#define XDL_MERGE_FAVOR(flags) (((flags)>>4) & 3) +#define XDL_MERGE_FLAGS(level, style, favor) ((level)|(style)|((favor)<<4)) + /* merge output styles */ #define XDL_MERGE_DIFF3 0x8000 #define XDL_MERGE_STYLE_MASK 0x8000 @@@ -114,9 -108,16 +114,16 @@@ long xdl_mmfile_size(mmfile_t *mmf) int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *ecb); + typedef struct s_xmparam { + xpparam_t xpp; + int marker_size; + } xmparam_t; + + #define DEFAULT_CONFLICT_MARKER_SIZE 7 + int xdl_merge(mmfile_t *orig, mmfile_t *mf1, const char *name1, mmfile_t *mf2, const char *name2, - xpparam_t const *xpp, int flags, mmbuffer_t *result); - xmparam_t const *xmp, int level, mmbuffer_t *result); ++ xmparam_t const *xmp, int flags, mmbuffer_t *result); #ifdef __cplusplus } diff --combined xdiff/xmerge.c index b2ddc75376,68c815f9d3..8cbe45e675 --- a/xdiff/xmerge.c +++ b/xdiff/xmerge.c @@@ -145,13 -145,15 +145,15 @@@ static int xdl_orig_copy(xdfenv_t *xe, static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1, xdfenv_t *xe2, const char *name2, int size, int i, int style, - xdmerge_t *m, char *dest) + xdmerge_t *m, char *dest, int marker_size) { - const int marker_size = 7; int marker1_size = (name1 ? strlen(name1) + 1 : 0); int marker2_size = (name2 ? strlen(name2) + 1 : 0); int j; + if (marker_size <= 0) + marker_size = DEFAULT_CONFLICT_MARKER_SIZE; + /* Before conflicting part */ size += xdl_recs_copy(xe1, i, m->i1 - i, 0, dest ? dest + size : NULL); @@@ -214,18 -216,16 +216,20 @@@ static int xdl_fill_merge_buffer(xdfenv_t *xe1, const char *name1, xdfenv_t *xe2, const char *name2, + int favor, - xdmerge_t *m, char *dest, int style) + xdmerge_t *m, char *dest, int style, + int marker_size) { int size, i; for (size = i = 0; m; m = m->next) { + if (favor && !m->mode) + m->mode = favor; + if (m->mode == 0) size = fill_conflict_hunk(xe1, name1, xe2, name2, - size, i, style, m, dest); + size, i, style, m, dest, + marker_size); else if (m->mode == 1) size += xdl_recs_copy(xe1, i, m->i1 + m->chg1 - i, 0, dest ? dest + size : NULL); @@@ -390,12 -390,12 +394,13 @@@ static int xdl_simplify_non_conflicts(x */ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, const char *name1, xdfenv_t *xe2, xdchange_t *xscr2, const char *name2, - int flags, xpparam_t const *xpp, mmbuffer_t *result) { + int flags, xmparam_t const *xmp, mmbuffer_t *result) { xdmerge_t *changes, *c; + xpparam_t const *xpp = &xmp->xpp; int i0, i1, i2, chg0, chg1, chg2; int level = flags & XDL_MERGE_LEVEL_MASK; int style = flags & XDL_MERGE_STYLE_MASK; + int favor = XDL_MERGE_FAVOR(flags); if (style == XDL_MERGE_DIFF3) { /* @@@ -527,26 -527,29 +532,29 @@@ } /* output */ if (result) { + int marker_size = xmp->marker_size; int size = xdl_fill_merge_buffer(xe1, name1, xe2, name2, - favor, changes, NULL, style); - changes, NULL, style, ++ favor, changes, NULL, style, + marker_size); result->ptr = xdl_malloc(size); if (!result->ptr) { xdl_cleanup_merge(changes); return -1; } result->size = size; - xdl_fill_merge_buffer(xe1, name1, xe2, name2, changes, + xdl_fill_merge_buffer(xe1, name1, xe2, name2, favor, changes, - result->ptr, style); + result->ptr, style, marker_size); } return xdl_cleanup_merge(changes); } int xdl_merge(mmfile_t *orig, mmfile_t *mf1, const char *name1, mmfile_t *mf2, const char *name2, - xpparam_t const *xpp, int flags, mmbuffer_t *result) { + xmparam_t const *xmp, int flags, mmbuffer_t *result) { xdchange_t *xscr1, *xscr2; xdfenv_t xe1, xe2; int status; + xpparam_t const *xpp = &xmp->xpp; result->ptr = NULL; result->size = 0; @@@ -579,7 -582,7 +587,7 @@@ } else { status = xdl_do_merge(&xe1, xscr1, name1, &xe2, xscr2, name2, - flags, xpp, result); + flags, xmp, result); } xdl_free_script(xscr1); xdl_free_script(xscr2);