Skip to content

Commit

Permalink
Merge branch 'jc/conflict-marker-size'
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
gitster committed Jan 21, 2010
2 parents df91d0e + 8588567 commit 06dbc1e
Show file tree
Hide file tree
Showing 16 changed files with 155 additions and 78 deletions.
4 changes: 2 additions & 2 deletions archive.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ static void setup_archive_check(struct git_attr_check *check)
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;
Expand Down
11 changes: 8 additions & 3 deletions attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static int invalid_attr_name(const char *name, int namelen)
return 0;
}

struct git_attr *git_attr(const char *name, int len)
static struct git_attr *git_attr_internal(const char *name, int len)
{
unsigned hval = hash_name(name, len);
unsigned pos = hval % HASHSIZE;
Expand Down Expand Up @@ -95,6 +95,11 @@ struct git_attr *git_attr(const char *name, int len)
return a;
}

struct git_attr *git_attr(const char *name)
{
return git_attr_internal(name, strlen(name));
}

/*
* .gitattributes file is one line per record, each of which is
*
Expand Down Expand Up @@ -162,7 +167,7 @@ static const char *parse_attr(const char *src, int lineno, const char *cp,
else {
e->setto = xmemdupz(equals + 1, ep - equals - 1);
}
e->attr = git_attr(cp, len);
e->attr = git_attr_internal(cp, len);
}
(*num_attr)++;
return ep + strspn(ep, blank);
Expand Down Expand Up @@ -221,7 +226,7 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
sizeof(struct attr_state) * num_attr +
(is_macro ? 0 : namelen + 1));
if (is_macro)
res->u.attr = git_attr(name, namelen);
res->u.attr = git_attr_internal(name, namelen);
else {
res->u.pattern = (char *)&(res->state[num_attr]);
memcpy(res->u.pattern, name, namelen);
Expand Down
2 changes: 1 addition & 1 deletion attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ struct git_attr;
* Given a string, return the gitattribute object that
* corresponds to it.
*/
struct git_attr *git_attr(const char *, int);
struct git_attr *git_attr(const char *);

/* Internal use */
extern const char git_attr__true[];
Expand Down
2 changes: 1 addition & 1 deletion builtin-check-attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)
const char *name;
struct git_attr *a;
name = argv[i];
a = git_attr(name, strlen(name));
a = git_attr(name);
if (!a)
return error("%s: not a valid attribute name", name);
check[i].attr = a;
Expand Down
4 changes: 2 additions & 2 deletions builtin-merge-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)
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 level = XDL_MERGE_ZEALOUS_ALNUM;
int style = 0, quiet = 0;
Expand Down Expand Up @@ -73,7 +73,7 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)
}

ret = xdl_merge(mmfs + 1, mmfs + 0, names[0], mmfs + 2, names[2],
&xpp, XDL_MERGE_FLAGS(level, style, favor), &result);
&xmp, XDL_MERGE_FLAGS(level, style, favor), &result);

for (i = 0; i < 3; i++)
free(mmfs[i].ptr);
Expand Down
2 changes: 1 addition & 1 deletion builtin-pack-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ static void setup_delta_attr_check(struct git_attr_check *check)
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;
}
Expand Down
6 changes: 3 additions & 3 deletions convert.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,9 +378,9 @@ static void setup_convert_check(struct git_attr_check *check)
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);
}
Expand Down
81 changes: 53 additions & 28 deletions ll-merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ typedef int (*ll_merge_fn)(const struct ll_merge_driver *,
mmfile_t *orig,
mmfile_t *src1, const char *name1,
mmfile_t *src2, const char *name2,
int flag);
int flag,
int marker_size);

struct ll_merge_driver {
const char *name;
Expand All @@ -38,7 +39,7 @@ static int ll_binary_merge(const struct ll_merge_driver *drv_unused,
mmfile_t *orig,
mmfile_t *src1, const char *name1,
mmfile_t *src2, const char *name2,
int flag)
int flag, int marker_size)
{
/*
* The tentative merge result is "ours" for the final round,
Expand All @@ -59,9 +60,9 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
mmfile_t *orig,
mmfile_t *src1, const char *name1,
mmfile_t *src2, const char *name2,
int flag)
int flag, int marker_size)
{
xpparam_t xpp;
xmparam_t xmp;
int style = 0;
int favor = (flag >> 1) & 03;

Expand All @@ -73,16 +74,19 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
return ll_binary_merge(drv_unused, result,
path,
orig, src1, name1,
src2, name2, flag);
src2, name2,
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_FLAGS(XDL_MERGE_ZEALOUS, style, favor),
result);
}

Expand All @@ -92,19 +96,18 @@ static int ll_union_merge(const struct ll_merge_driver *drv_unused,
mmfile_t *orig,
mmfile_t *src1, const char *name1,
mmfile_t *src2, const char *name2,
int flag)
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 */
saved_style = git_xmerge_style;
git_xmerge_style = 0;
status = ll_xdl_merge(drv_unused, result, path_unused,
orig, src1, NULL, src2, NULL,
flag);
flag, marker_size);
git_xmerge_style = saved_style;
if (status <= 0)
return status;
Expand Down Expand Up @@ -165,14 +168,15 @@ static int ll_ext_merge(const struct ll_merge_driver *fn,
mmfile_t *orig,
mmfile_t *src1, const char *name1,
mmfile_t *src2, const char *name2,
int flag)
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[] = { NULL, NULL };
Expand All @@ -187,6 +191,7 @@ static int ll_ext_merge(const struct ll_merge_driver *fn,
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);

Expand Down Expand Up @@ -279,6 +284,7 @@ static int read_merge_config(const char *var, const char *value, void *cb)
* %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
Expand Down Expand Up @@ -339,16 +345,13 @@ static const struct ll_merge_driver *find_ll_merge_driver(const char *merge_attr
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,
Expand All @@ -358,17 +361,39 @@ int ll_merge(mmbuffer_t *result_buf,
mmfile_t *theirs, const char *their_label,
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,
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;
}
2 changes: 2 additions & 0 deletions ll-merge.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ int ll_merge(mmbuffer_t *result_buf,
mmfile_t *theirs, const char *their_label,
int flag);

int ll_merge_marker_size(const char *path);

#endif
16 changes: 7 additions & 9 deletions merge-file.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "cache.h"
#include "run-command.h"
#include "xdiff-interface.h"
#include "ll-merge.h"
#include "blob.h"

static int fill_mmfile_blob(mmfile_t *f, struct blob *obj)
Expand All @@ -24,16 +25,13 @@ static void free_mmfile(mmfile_t *f)
free(f->ptr);
}

static void *three_way_filemerge(mmfile_t *base, mmfile_t *our, mmfile_t *their, unsigned long *size)
static void *three_way_filemerge(const char *path, mmfile_t *base, mmfile_t *our, mmfile_t *their, unsigned long *size)
{
mmbuffer_t res;
xpparam_t xpp;
int merge_status;
mmbuffer_t res;

memset(&xpp, 0, sizeof(xpp));
merge_status = xdl_merge(base, our, ".our", their, ".their",
&xpp, XDL_MERGE_ZEALOUS, &res);

merge_status = ll_merge(&res, path, base,
our, ".our", their, ".their", 0);
if (merge_status < 0)
return NULL;

Expand Down Expand Up @@ -75,7 +73,7 @@ static int generate_common_file(mmfile_t *res, mmfile_t *f1, mmfile_t *f2)
return xdi_diff(f1, f2, &xpp, &xecfg, &ecb);
}

void *merge_file(struct blob *base, struct blob *our, struct blob *their, unsigned long *size)
void *merge_file(const char *path, struct blob *base, struct blob *our, struct blob *their, unsigned long *size)
{
void *res = NULL;
mmfile_t f1, f2, common;
Expand Down Expand Up @@ -108,7 +106,7 @@ void *merge_file(struct blob *base, struct blob *our, struct blob *their, unsign
if (generate_common_file(&common, &f1, &f2) < 0)
goto out_free_f2_f1;
}
res = three_way_filemerge(&common, &f1, &f2, size);
res = three_way_filemerge(path, &common, &f1, &f2, size);
free_mmfile(&common);
out_free_f2_f1:
free_mmfile(&f2);
Expand Down
4 changes: 2 additions & 2 deletions merge-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ static const char *explanation(struct merge_list *entry)
return "removed in remote";
}

extern void *merge_file(struct blob *, struct blob *, struct blob *, unsigned long *);
extern void *merge_file(const char *, struct blob *, struct blob *, struct blob *, unsigned long *);

static void *result(struct merge_list *entry, unsigned long *size)
{
Expand All @@ -76,7 +76,7 @@ static void *result(struct merge_list *entry, unsigned long *size)
their = NULL;
if (entry)
their = entry->blob;
return merge_file(base, our, their, size);
return merge_file(entry->path, base, our, their, size);
}

static void *origin(struct merge_list *entry, unsigned long *size)
Expand Down
Loading

0 comments on commit 06dbc1e

Please sign in to comment.