Skip to content

Commit b779b3a

Browse files
peffgitster
authored andcommitted
merge-tree: drop generate_common strategy
When merge_blobs sees an add/add conflict, it tries to create a virtual base object for the 3-way merge that consists of the common lines of each file. It inherited this strategy from merge-one-file in 0c79938 (Improved three-way blob merging code, 2006-06-28), and the point is to minimize the size of the conflict hunks. That commit talks about "if libxdiff were to ever grow a compatible three-way merge, it could probably be directly plugged in". That has long since happened. So as with merge-one-file in the previous commit, this extra step is no longer necessary. Our 3-way merge code is smart enough to do the minimizing itself if we simply feed it an empty base, which is what the more modern merge-recursive strategy already does. Not only does this let us drop some code, but it removes an overflow bug in generate_common_file(). We allocate a buffer as large as the smallest of the two blobs, under the assumption that there cannot be more common content than what is in the smaller blob. However, xdiff may feed us more: if neither file ends in a newline, it feeds us the "\nNo newline at end of file" marker as common content, and we write it into the output. If the differences between the files are small than that string, we overflow the output buffer. This patch solves it by simply dropping the buggy code entirely. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 1a92e53 commit b779b3a

File tree

1 file changed

+2
-36
lines changed

1 file changed

+2
-36
lines changed

merge-blobs.c

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -48,40 +48,6 @@ static void *three_way_filemerge(const char *path, mmfile_t *base, mmfile_t *our
4848
return res.ptr;
4949
}
5050

51-
static int common_outf(void *priv_, mmbuffer_t *mb, int nbuf)
52-
{
53-
int i;
54-
mmfile_t *dst = priv_;
55-
56-
for (i = 0; i < nbuf; i++) {
57-
memcpy(dst->ptr + dst->size, mb[i].ptr, mb[i].size);
58-
dst->size += mb[i].size;
59-
}
60-
return 0;
61-
}
62-
63-
static int generate_common_file(mmfile_t *res, mmfile_t *f1, mmfile_t *f2)
64-
{
65-
unsigned long size = f1->size < f2->size ? f1->size : f2->size;
66-
void *ptr = xmalloc(size);
67-
xpparam_t xpp;
68-
xdemitconf_t xecfg;
69-
xdemitcb_t ecb;
70-
71-
memset(&xpp, 0, sizeof(xpp));
72-
xpp.flags = 0;
73-
memset(&xecfg, 0, sizeof(xecfg));
74-
xecfg.ctxlen = 3;
75-
xecfg.flags = XDL_EMIT_COMMON;
76-
ecb.outf = common_outf;
77-
78-
res->ptr = ptr;
79-
res->size = 0;
80-
81-
ecb.priv = res;
82-
return xdi_diff(f1, f2, &xpp, &xecfg, &ecb);
83-
}
84-
8551
void *merge_blobs(const char *path, struct blob *base, struct blob *our, struct blob *their, unsigned long *size)
8652
{
8753
void *res = NULL;
@@ -112,8 +78,8 @@ void *merge_blobs(const char *path, struct blob *base, struct blob *our, struct
11278
if (fill_mmfile_blob(&common, base) < 0)
11379
goto out_free_f2_f1;
11480
} else {
115-
if (generate_common_file(&common, &f1, &f2) < 0)
116-
goto out_free_f2_f1;
81+
common.ptr = xstrdup("");
82+
common.size = 0;
11783
}
11884
res = three_way_filemerge(path, &common, &f1, &f2, size);
11985
free_mmfile(&common);

0 commit comments

Comments
 (0)