|
|
|
|
@@ -278,13 +278,26 @@ struct line {
|
|
|
|
|
* This represents a "file", which is an array of "lines".
|
|
|
|
|
*/
|
|
|
|
|
struct image {
|
|
|
|
|
char *buf;
|
|
|
|
|
size_t len;
|
|
|
|
|
size_t nr;
|
|
|
|
|
size_t alloc;
|
|
|
|
|
struct line *line_allocated;
|
|
|
|
|
struct strbuf buf;
|
|
|
|
|
struct line *line;
|
|
|
|
|
size_t line_nr, line_alloc;
|
|
|
|
|
};
|
|
|
|
|
#define IMAGE_INIT { \
|
|
|
|
|
.buf = STRBUF_INIT, \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void image_init(struct image *image)
|
|
|
|
|
{
|
|
|
|
|
struct image empty = IMAGE_INIT;
|
|
|
|
|
memcpy(image, &empty, sizeof(*image));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void image_clear(struct image *image)
|
|
|
|
|
{
|
|
|
|
|
strbuf_release(&image->buf);
|
|
|
|
|
free(image->line);
|
|
|
|
|
image_init(image);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint32_t hash_line(const char *cp, size_t len)
|
|
|
|
|
{
|
|
|
|
|
@@ -298,49 +311,13 @@ static uint32_t hash_line(const char *cp, size_t len)
|
|
|
|
|
return h;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Compare lines s1 of length n1 and s2 of length n2, ignoring
|
|
|
|
|
* whitespace difference. Returns 1 if they match, 0 otherwise
|
|
|
|
|
*/
|
|
|
|
|
static int fuzzy_matchlines(const char *s1, size_t n1,
|
|
|
|
|
const char *s2, size_t n2)
|
|
|
|
|
static void image_add_line(struct image *img, const char *bol, size_t len, unsigned flag)
|
|
|
|
|
{
|
|
|
|
|
const char *end1 = s1 + n1;
|
|
|
|
|
const char *end2 = s2 + n2;
|
|
|
|
|
|
|
|
|
|
/* ignore line endings */
|
|
|
|
|
while (s1 < end1 && (end1[-1] == '\r' || end1[-1] == '\n'))
|
|
|
|
|
end1--;
|
|
|
|
|
while (s2 < end2 && (end2[-1] == '\r' || end2[-1] == '\n'))
|
|
|
|
|
end2--;
|
|
|
|
|
|
|
|
|
|
while (s1 < end1 && s2 < end2) {
|
|
|
|
|
if (isspace(*s1)) {
|
|
|
|
|
/*
|
|
|
|
|
* Skip whitespace. We check on both buffers
|
|
|
|
|
* because we don't want "a b" to match "ab".
|
|
|
|
|
*/
|
|
|
|
|
if (!isspace(*s2))
|
|
|
|
|
return 0;
|
|
|
|
|
while (s1 < end1 && isspace(*s1))
|
|
|
|
|
s1++;
|
|
|
|
|
while (s2 < end2 && isspace(*s2))
|
|
|
|
|
s2++;
|
|
|
|
|
} else if (*s1++ != *s2++)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If we reached the end on one side only, lines don't match. */
|
|
|
|
|
return s1 == end1 && s2 == end2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void add_line_info(struct image *img, const char *bol, size_t len, unsigned flag)
|
|
|
|
|
{
|
|
|
|
|
ALLOC_GROW(img->line_allocated, img->nr + 1, img->alloc);
|
|
|
|
|
img->line_allocated[img->nr].len = len;
|
|
|
|
|
img->line_allocated[img->nr].hash = hash_line(bol, len);
|
|
|
|
|
img->line_allocated[img->nr].flag = flag;
|
|
|
|
|
img->nr++;
|
|
|
|
|
ALLOC_GROW(img->line, img->line_nr + 1, img->line_alloc);
|
|
|
|
|
img->line[img->line_nr].len = len;
|
|
|
|
|
img->line[img->line_nr].hash = hash_line(bol, len);
|
|
|
|
|
img->line[img->line_nr].flag = flag;
|
|
|
|
|
img->line_nr++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
@@ -348,37 +325,43 @@ static void add_line_info(struct image *img, const char *bol, size_t len, unsign
|
|
|
|
|
* attach it to "image" and add line-based index to it.
|
|
|
|
|
* "image" now owns the "buf".
|
|
|
|
|
*/
|
|
|
|
|
static void prepare_image(struct image *image, char *buf, size_t len,
|
|
|
|
|
static void image_prepare(struct image *image, char *buf, size_t len,
|
|
|
|
|
int prepare_linetable)
|
|
|
|
|
{
|
|
|
|
|
const char *cp, *ep;
|
|
|
|
|
|
|
|
|
|
memset(image, 0, sizeof(*image));
|
|
|
|
|
image->buf = buf;
|
|
|
|
|
image->len = len;
|
|
|
|
|
image_clear(image);
|
|
|
|
|
strbuf_attach(&image->buf, buf, len, len + 1);
|
|
|
|
|
|
|
|
|
|
if (!prepare_linetable)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ep = image->buf + image->len;
|
|
|
|
|
cp = image->buf;
|
|
|
|
|
ep = image->buf.buf + image->buf.len;
|
|
|
|
|
cp = image->buf.buf;
|
|
|
|
|
while (cp < ep) {
|
|
|
|
|
const char *next;
|
|
|
|
|
for (next = cp; next < ep && *next != '\n'; next++)
|
|
|
|
|
;
|
|
|
|
|
if (next < ep)
|
|
|
|
|
next++;
|
|
|
|
|
add_line_info(image, cp, next - cp, 0);
|
|
|
|
|
image_add_line(image, cp, next - cp, 0);
|
|
|
|
|
cp = next;
|
|
|
|
|
}
|
|
|
|
|
image->line = image->line_allocated;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void clear_image(struct image *image)
|
|
|
|
|
static void image_remove_first_line(struct image *img)
|
|
|
|
|
{
|
|
|
|
|
free(image->buf);
|
|
|
|
|
free(image->line_allocated);
|
|
|
|
|
memset(image, 0, sizeof(*image));
|
|
|
|
|
strbuf_remove(&img->buf, 0, img->line[0].len);
|
|
|
|
|
img->line_nr--;
|
|
|
|
|
if (img->line_nr)
|
|
|
|
|
MOVE_ARRAY(img->line, img->line + 1, img->line_nr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void image_remove_last_line(struct image *img)
|
|
|
|
|
{
|
|
|
|
|
size_t last_line_len = img->line[img->line_nr - 1].len;
|
|
|
|
|
strbuf_setlen(&img->buf, img->buf.len - last_line_len);
|
|
|
|
|
img->line_nr--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* fmt must contain _one_ %s and no other substitution */
|
|
|
|
|
@@ -2327,65 +2310,43 @@ static int read_old_data(struct stat *st, struct patch *patch,
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Update the preimage, and the common lines in postimage,
|
|
|
|
|
* from buffer buf of length len. If postlen is 0 the postimage
|
|
|
|
|
* is updated in place, otherwise it's updated on a new buffer
|
|
|
|
|
* of length postlen
|
|
|
|
|
* from buffer buf of length len.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static void update_pre_post_images(struct image *preimage,
|
|
|
|
|
struct image *postimage,
|
|
|
|
|
char *buf,
|
|
|
|
|
size_t len, size_t postlen)
|
|
|
|
|
char *buf, size_t len)
|
|
|
|
|
{
|
|
|
|
|
struct image fixed_preimage = IMAGE_INIT;
|
|
|
|
|
size_t insert_pos = 0;
|
|
|
|
|
int i, ctx, reduced;
|
|
|
|
|
char *new_buf, *old_buf, *fixed;
|
|
|
|
|
struct image fixed_preimage;
|
|
|
|
|
const char *fixed;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Update the preimage with whitespace fixes. Note that we
|
|
|
|
|
* are not losing preimage->buf -- apply_one_fragment() will
|
|
|
|
|
* free "oldlines".
|
|
|
|
|
*/
|
|
|
|
|
prepare_image(&fixed_preimage, buf, len, 1);
|
|
|
|
|
assert(postlen
|
|
|
|
|
? fixed_preimage.nr == preimage->nr
|
|
|
|
|
: fixed_preimage.nr <= preimage->nr);
|
|
|
|
|
for (i = 0; i < fixed_preimage.nr; i++)
|
|
|
|
|
image_prepare(&fixed_preimage, buf, len, 1);
|
|
|
|
|
for (i = 0; i < fixed_preimage.line_nr; i++)
|
|
|
|
|
fixed_preimage.line[i].flag = preimage->line[i].flag;
|
|
|
|
|
free(preimage->line_allocated);
|
|
|
|
|
image_clear(preimage);
|
|
|
|
|
*preimage = fixed_preimage;
|
|
|
|
|
fixed = preimage->buf.buf;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Adjust the common context lines in postimage. This can be
|
|
|
|
|
* done in-place when we are shrinking it with whitespace
|
|
|
|
|
* fixing, but needs a new buffer when ignoring whitespace or
|
|
|
|
|
* expanding leading tabs to spaces.
|
|
|
|
|
*
|
|
|
|
|
* We trust the caller to tell us if the update can be done
|
|
|
|
|
* in place (postlen==0) or not.
|
|
|
|
|
* Adjust the common context lines in postimage.
|
|
|
|
|
*/
|
|
|
|
|
old_buf = postimage->buf;
|
|
|
|
|
if (postlen)
|
|
|
|
|
new_buf = postimage->buf = xmalloc(postlen);
|
|
|
|
|
else
|
|
|
|
|
new_buf = old_buf;
|
|
|
|
|
fixed = preimage->buf;
|
|
|
|
|
|
|
|
|
|
for (i = reduced = ctx = 0; i < postimage->nr; i++) {
|
|
|
|
|
for (i = reduced = ctx = 0; i < postimage->line_nr; i++) {
|
|
|
|
|
size_t l_len = postimage->line[i].len;
|
|
|
|
|
|
|
|
|
|
if (!(postimage->line[i].flag & LINE_COMMON)) {
|
|
|
|
|
/* an added line -- no counterparts in preimage */
|
|
|
|
|
memmove(new_buf, old_buf, l_len);
|
|
|
|
|
old_buf += l_len;
|
|
|
|
|
new_buf += l_len;
|
|
|
|
|
insert_pos += l_len;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* a common context -- skip it in the original postimage */
|
|
|
|
|
old_buf += l_len;
|
|
|
|
|
|
|
|
|
|
/* and find the corresponding one in the fixed preimage */
|
|
|
|
|
while (ctx < preimage->nr &&
|
|
|
|
|
while (ctx < preimage->line_nr &&
|
|
|
|
|
!(preimage->line[ctx].flag & LINE_COMMON)) {
|
|
|
|
|
fixed += preimage->line[ctx].len;
|
|
|
|
|
ctx++;
|
|
|
|
|
@@ -2395,29 +2356,59 @@ static void update_pre_post_images(struct image *preimage,
|
|
|
|
|
* preimage is expected to run out, if the caller
|
|
|
|
|
* fixed addition of trailing blank lines.
|
|
|
|
|
*/
|
|
|
|
|
if (preimage->nr <= ctx) {
|
|
|
|
|
if (preimage->line_nr <= ctx) {
|
|
|
|
|
reduced++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* and copy it in, while fixing the line length */
|
|
|
|
|
l_len = preimage->line[ctx].len;
|
|
|
|
|
memcpy(new_buf, fixed, l_len);
|
|
|
|
|
new_buf += l_len;
|
|
|
|
|
strbuf_splice(&postimage->buf, insert_pos, postimage->line[i].len,
|
|
|
|
|
fixed, l_len);
|
|
|
|
|
insert_pos += l_len;
|
|
|
|
|
fixed += l_len;
|
|
|
|
|
postimage->line[i].len = l_len;
|
|
|
|
|
ctx++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (postlen
|
|
|
|
|
? postlen < new_buf - postimage->buf
|
|
|
|
|
: postimage->len < new_buf - postimage->buf)
|
|
|
|
|
BUG("caller miscounted postlen: asked %d, orig = %d, used = %d",
|
|
|
|
|
(int)postlen, (int) postimage->len, (int)(new_buf - postimage->buf));
|
|
|
|
|
|
|
|
|
|
/* Fix the length of the whole thing */
|
|
|
|
|
postimage->len = new_buf - postimage->buf;
|
|
|
|
|
postimage->nr -= reduced;
|
|
|
|
|
postimage->line_nr -= reduced;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Compare lines s1 of length n1 and s2 of length n2, ignoring
|
|
|
|
|
* whitespace difference. Returns 1 if they match, 0 otherwise
|
|
|
|
|
*/
|
|
|
|
|
static int fuzzy_matchlines(const char *s1, size_t n1,
|
|
|
|
|
const char *s2, size_t n2)
|
|
|
|
|
{
|
|
|
|
|
const char *end1 = s1 + n1;
|
|
|
|
|
const char *end2 = s2 + n2;
|
|
|
|
|
|
|
|
|
|
/* ignore line endings */
|
|
|
|
|
while (s1 < end1 && (end1[-1] == '\r' || end1[-1] == '\n'))
|
|
|
|
|
end1--;
|
|
|
|
|
while (s2 < end2 && (end2[-1] == '\r' || end2[-1] == '\n'))
|
|
|
|
|
end2--;
|
|
|
|
|
|
|
|
|
|
while (s1 < end1 && s2 < end2) {
|
|
|
|
|
if (isspace(*s1)) {
|
|
|
|
|
/*
|
|
|
|
|
* Skip whitespace. We check on both buffers
|
|
|
|
|
* because we don't want "a b" to match "ab".
|
|
|
|
|
*/
|
|
|
|
|
if (!isspace(*s2))
|
|
|
|
|
return 0;
|
|
|
|
|
while (s1 < end1 && isspace(*s1))
|
|
|
|
|
s1++;
|
|
|
|
|
while (s2 < end2 && isspace(*s2))
|
|
|
|
|
s2++;
|
|
|
|
|
} else if (*s1++ != *s2++)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If we reached the end on one side only, lines don't match. */
|
|
|
|
|
return s1 == end1 && s2 == end2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int line_by_line_fuzzy_match(struct image *img,
|
|
|
|
|
@@ -2430,7 +2421,6 @@ static int line_by_line_fuzzy_match(struct image *img,
|
|
|
|
|
int i;
|
|
|
|
|
size_t imgoff = 0;
|
|
|
|
|
size_t preoff = 0;
|
|
|
|
|
size_t postlen = postimage->len;
|
|
|
|
|
size_t extra_chars;
|
|
|
|
|
char *buf;
|
|
|
|
|
char *preimage_eof;
|
|
|
|
|
@@ -2443,11 +2433,9 @@ static int line_by_line_fuzzy_match(struct image *img,
|
|
|
|
|
size_t prelen = preimage->line[i].len;
|
|
|
|
|
size_t imglen = img->line[current_lno+i].len;
|
|
|
|
|
|
|
|
|
|
if (!fuzzy_matchlines(img->buf + current + imgoff, imglen,
|
|
|
|
|
preimage->buf + preoff, prelen))
|
|
|
|
|
if (!fuzzy_matchlines(img->buf.buf + current + imgoff, imglen,
|
|
|
|
|
preimage->buf.buf + preoff, prelen))
|
|
|
|
|
return 0;
|
|
|
|
|
if (preimage->line[i].flag & LINE_COMMON)
|
|
|
|
|
postlen += imglen - prelen;
|
|
|
|
|
imgoff += imglen;
|
|
|
|
|
preoff += prelen;
|
|
|
|
|
}
|
|
|
|
|
@@ -2463,10 +2451,10 @@ static int line_by_line_fuzzy_match(struct image *img,
|
|
|
|
|
* are whitespace characters. (This can only happen if
|
|
|
|
|
* we are removing blank lines at the end of the file.)
|
|
|
|
|
*/
|
|
|
|
|
buf = preimage_eof = preimage->buf + preoff;
|
|
|
|
|
for ( ; i < preimage->nr; i++)
|
|
|
|
|
buf = preimage_eof = preimage->buf.buf + preoff;
|
|
|
|
|
for ( ; i < preimage->line_nr; i++)
|
|
|
|
|
preoff += preimage->line[i].len;
|
|
|
|
|
preimage_end = preimage->buf + preoff;
|
|
|
|
|
preimage_end = preimage->buf.buf + preoff;
|
|
|
|
|
for ( ; buf < preimage_end; buf++)
|
|
|
|
|
if (!isspace(*buf))
|
|
|
|
|
return 0;
|
|
|
|
|
@@ -2480,11 +2468,11 @@ static int line_by_line_fuzzy_match(struct image *img,
|
|
|
|
|
*/
|
|
|
|
|
extra_chars = preimage_end - preimage_eof;
|
|
|
|
|
strbuf_init(&fixed, imgoff + extra_chars);
|
|
|
|
|
strbuf_add(&fixed, img->buf + current, imgoff);
|
|
|
|
|
strbuf_add(&fixed, img->buf.buf + current, imgoff);
|
|
|
|
|
strbuf_add(&fixed, preimage_eof, extra_chars);
|
|
|
|
|
fixed_buf = strbuf_detach(&fixed, &fixed_len);
|
|
|
|
|
update_pre_post_images(preimage, postimage,
|
|
|
|
|
fixed_buf, fixed_len, postlen);
|
|
|
|
|
fixed_buf, fixed_len);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2500,16 +2488,17 @@ static int match_fragment(struct apply_state *state,
|
|
|
|
|
int i;
|
|
|
|
|
const char *orig, *target;
|
|
|
|
|
struct strbuf fixed = STRBUF_INIT;
|
|
|
|
|
size_t postlen;
|
|
|
|
|
char *fixed_buf;
|
|
|
|
|
size_t fixed_len;
|
|
|
|
|
int preimage_limit;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
if (preimage->nr + current_lno <= img->nr) {
|
|
|
|
|
if (preimage->line_nr + current_lno <= img->line_nr) {
|
|
|
|
|
/*
|
|
|
|
|
* The hunk falls within the boundaries of img.
|
|
|
|
|
*/
|
|
|
|
|
preimage_limit = preimage->nr;
|
|
|
|
|
if (match_end && (preimage->nr + current_lno != img->nr)) {
|
|
|
|
|
preimage_limit = preimage->line_nr;
|
|
|
|
|
if (match_end && (preimage->line_nr + current_lno != img->line_nr)) {
|
|
|
|
|
ret = 0;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
@@ -2522,7 +2511,7 @@ static int match_fragment(struct apply_state *state,
|
|
|
|
|
* match with img, and the remainder of the preimage
|
|
|
|
|
* must be blank.
|
|
|
|
|
*/
|
|
|
|
|
preimage_limit = img->nr - current_lno;
|
|
|
|
|
preimage_limit = img->line_nr - current_lno;
|
|
|
|
|
} else {
|
|
|
|
|
/*
|
|
|
|
|
* The hunk extends beyond the end of the img and
|
|
|
|
|
@@ -2547,7 +2536,7 @@ static int match_fragment(struct apply_state *state,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (preimage_limit == preimage->nr) {
|
|
|
|
|
if (preimage_limit == preimage->line_nr) {
|
|
|
|
|
/*
|
|
|
|
|
* Do we have an exact match? If we were told to match
|
|
|
|
|
* at the end, size must be exactly at current+fragsize,
|
|
|
|
|
@@ -2556,9 +2545,9 @@ static int match_fragment(struct apply_state *state,
|
|
|
|
|
* exactly.
|
|
|
|
|
*/
|
|
|
|
|
if ((match_end
|
|
|
|
|
? (current + preimage->len == img->len)
|
|
|
|
|
: (current + preimage->len <= img->len)) &&
|
|
|
|
|
!memcmp(img->buf + current, preimage->buf, preimage->len)) {
|
|
|
|
|
? (current + preimage->buf.len == img->buf.len)
|
|
|
|
|
: (current + preimage->buf.len <= img->buf.len)) &&
|
|
|
|
|
!memcmp(img->buf.buf + current, preimage->buf.buf, preimage->buf.len)) {
|
|
|
|
|
ret = 1;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
@@ -2572,7 +2561,7 @@ static int match_fragment(struct apply_state *state,
|
|
|
|
|
*/
|
|
|
|
|
const char *buf, *buf_end;
|
|
|
|
|
|
|
|
|
|
buf = preimage->buf;
|
|
|
|
|
buf = preimage->buf.buf;
|
|
|
|
|
buf_end = buf;
|
|
|
|
|
for (i = 0; i < preimage_limit; i++)
|
|
|
|
|
buf_end += preimage->line[i].len;
|
|
|
|
|
@@ -2617,21 +2606,14 @@ static int match_fragment(struct apply_state *state,
|
|
|
|
|
* fixed.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* First count added lines in postimage */
|
|
|
|
|
postlen = 0;
|
|
|
|
|
for (i = 0; i < postimage->nr; i++) {
|
|
|
|
|
if (!(postimage->line[i].flag & LINE_COMMON))
|
|
|
|
|
postlen += postimage->line[i].len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The preimage may extend beyond the end of the file,
|
|
|
|
|
* but in this loop we will only handle the part of the
|
|
|
|
|
* preimage that falls within the file.
|
|
|
|
|
*/
|
|
|
|
|
strbuf_grow(&fixed, preimage->len + 1);
|
|
|
|
|
orig = preimage->buf;
|
|
|
|
|
target = img->buf + current;
|
|
|
|
|
strbuf_grow(&fixed, preimage->buf.len + 1);
|
|
|
|
|
orig = preimage->buf.buf;
|
|
|
|
|
target = img->buf.buf + current;
|
|
|
|
|
for (i = 0; i < preimage_limit; i++) {
|
|
|
|
|
size_t oldlen = preimage->line[i].len;
|
|
|
|
|
size_t tgtlen = img->line[current_lno + i].len;
|
|
|
|
|
@@ -2660,10 +2642,6 @@ static int match_fragment(struct apply_state *state,
|
|
|
|
|
!memcmp(tgtfix.buf, fixed.buf + fixstart,
|
|
|
|
|
fixed.len - fixstart));
|
|
|
|
|
|
|
|
|
|
/* Add the length if this is common with the postimage */
|
|
|
|
|
if (preimage->line[i].flag & LINE_COMMON)
|
|
|
|
|
postlen += tgtfix.len;
|
|
|
|
|
|
|
|
|
|
strbuf_release(&tgtfix);
|
|
|
|
|
if (!match) {
|
|
|
|
|
ret = 0;
|
|
|
|
|
@@ -2681,7 +2659,7 @@ static int match_fragment(struct apply_state *state,
|
|
|
|
|
* empty or only contain whitespace (if WS_BLANK_AT_EOL is
|
|
|
|
|
* false).
|
|
|
|
|
*/
|
|
|
|
|
for ( ; i < preimage->nr; i++) {
|
|
|
|
|
for ( ; i < preimage->line_nr; i++) {
|
|
|
|
|
size_t fixstart = fixed.len; /* start of the fixed preimage */
|
|
|
|
|
size_t oldlen = preimage->line[i].len;
|
|
|
|
|
int j;
|
|
|
|
|
@@ -2705,10 +2683,9 @@ static int match_fragment(struct apply_state *state,
|
|
|
|
|
* has whitespace breakages unfixed, and fixing them makes the
|
|
|
|
|
* hunk match. Update the context lines in the postimage.
|
|
|
|
|
*/
|
|
|
|
|
if (postlen < postimage->len)
|
|
|
|
|
postlen = 0;
|
|
|
|
|
fixed_buf = strbuf_detach(&fixed, &fixed_len);
|
|
|
|
|
update_pre_post_images(preimage, postimage,
|
|
|
|
|
fixed.buf, fixed.len, postlen);
|
|
|
|
|
fixed_buf, fixed_len);
|
|
|
|
|
|
|
|
|
|
ret = 1;
|
|
|
|
|
|
|
|
|
|
@@ -2736,7 +2713,7 @@ static int find_pos(struct apply_state *state,
|
|
|
|
|
* than `match_beginning`.
|
|
|
|
|
*/
|
|
|
|
|
if (state->allow_overlap && match_beginning && match_end &&
|
|
|
|
|
img->nr - preimage->nr != 0)
|
|
|
|
|
img->line_nr - preimage->line_nr != 0)
|
|
|
|
|
match_beginning = 0;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
@@ -2747,15 +2724,15 @@ static int find_pos(struct apply_state *state,
|
|
|
|
|
if (match_beginning)
|
|
|
|
|
line = 0;
|
|
|
|
|
else if (match_end)
|
|
|
|
|
line = img->nr - preimage->nr;
|
|
|
|
|
line = img->line_nr - preimage->line_nr;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Because the comparison is unsigned, the following test
|
|
|
|
|
* will also take care of a negative line number that can
|
|
|
|
|
* result when match_end and preimage is larger than the target.
|
|
|
|
|
*/
|
|
|
|
|
if ((size_t) line > img->nr)
|
|
|
|
|
line = img->nr;
|
|
|
|
|
if ((size_t) line > img->line_nr)
|
|
|
|
|
line = img->line_nr;
|
|
|
|
|
|
|
|
|
|
current = 0;
|
|
|
|
|
for (i = 0; i < line; i++)
|
|
|
|
|
@@ -2778,7 +2755,7 @@ static int find_pos(struct apply_state *state,
|
|
|
|
|
return current_lno;
|
|
|
|
|
|
|
|
|
|
again:
|
|
|
|
|
if (backwards_lno == 0 && forwards_lno == img->nr)
|
|
|
|
|
if (backwards_lno == 0 && forwards_lno == img->line_nr)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if (i & 1) {
|
|
|
|
|
@@ -2791,7 +2768,7 @@ static int find_pos(struct apply_state *state,
|
|
|
|
|
current = backwards;
|
|
|
|
|
current_lno = backwards_lno;
|
|
|
|
|
} else {
|
|
|
|
|
if (forwards_lno == img->nr) {
|
|
|
|
|
if (forwards_lno == img->line_nr) {
|
|
|
|
|
i++;
|
|
|
|
|
goto again;
|
|
|
|
|
}
|
|
|
|
|
@@ -2805,19 +2782,6 @@ static int find_pos(struct apply_state *state,
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void remove_first_line(struct image *img)
|
|
|
|
|
{
|
|
|
|
|
img->buf += img->line[0].len;
|
|
|
|
|
img->len -= img->line[0].len;
|
|
|
|
|
img->line++;
|
|
|
|
|
img->nr--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void remove_last_line(struct image *img)
|
|
|
|
|
{
|
|
|
|
|
img->len -= img->line[--img->nr].len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The change from "preimage" and "postimage" has been found to
|
|
|
|
|
* apply at applied_pos (counts in line numbers) in "img".
|
|
|
|
|
@@ -2835,6 +2799,7 @@ static void update_image(struct apply_state *state,
|
|
|
|
|
*/
|
|
|
|
|
int i, nr;
|
|
|
|
|
size_t remove_count, insert_count, applied_at = 0;
|
|
|
|
|
size_t result_alloc;
|
|
|
|
|
char *result;
|
|
|
|
|
int preimage_limit;
|
|
|
|
|
|
|
|
|
|
@@ -2847,9 +2812,9 @@ static void update_image(struct apply_state *state,
|
|
|
|
|
* to the number of lines in the preimage that falls
|
|
|
|
|
* within the boundaries.
|
|
|
|
|
*/
|
|
|
|
|
preimage_limit = preimage->nr;
|
|
|
|
|
if (preimage_limit > img->nr - applied_pos)
|
|
|
|
|
preimage_limit = img->nr - applied_pos;
|
|
|
|
|
preimage_limit = preimage->line_nr;
|
|
|
|
|
if (preimage_limit > img->line_nr - applied_pos)
|
|
|
|
|
preimage_limit = img->line_nr - applied_pos;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < applied_pos; i++)
|
|
|
|
|
applied_at += img->line[i].len;
|
|
|
|
|
@@ -2857,39 +2822,36 @@ static void update_image(struct apply_state *state,
|
|
|
|
|
remove_count = 0;
|
|
|
|
|
for (i = 0; i < preimage_limit; i++)
|
|
|
|
|
remove_count += img->line[applied_pos + i].len;
|
|
|
|
|
insert_count = postimage->len;
|
|
|
|
|
insert_count = postimage->buf.len;
|
|
|
|
|
|
|
|
|
|
/* Adjust the contents */
|
|
|
|
|
result = xmalloc(st_add3(st_sub(img->len, remove_count), insert_count, 1));
|
|
|
|
|
memcpy(result, img->buf, applied_at);
|
|
|
|
|
memcpy(result + applied_at, postimage->buf, postimage->len);
|
|
|
|
|
memcpy(result + applied_at + postimage->len,
|
|
|
|
|
img->buf + (applied_at + remove_count),
|
|
|
|
|
img->len - (applied_at + remove_count));
|
|
|
|
|
free(img->buf);
|
|
|
|
|
img->buf = result;
|
|
|
|
|
img->len += insert_count - remove_count;
|
|
|
|
|
result[img->len] = '\0';
|
|
|
|
|
result_alloc = st_add3(st_sub(img->buf.len, remove_count), insert_count, 1);
|
|
|
|
|
result = xmalloc(result_alloc);
|
|
|
|
|
memcpy(result, img->buf.buf, applied_at);
|
|
|
|
|
memcpy(result + applied_at, postimage->buf.buf, postimage->buf.len);
|
|
|
|
|
memcpy(result + applied_at + postimage->buf.len,
|
|
|
|
|
img->buf.buf + (applied_at + remove_count),
|
|
|
|
|
img->buf.len - (applied_at + remove_count));
|
|
|
|
|
strbuf_attach(&img->buf, result, postimage->buf.len + img->buf.len - remove_count,
|
|
|
|
|
result_alloc);
|
|
|
|
|
|
|
|
|
|
/* Adjust the line table */
|
|
|
|
|
nr = img->nr + postimage->nr - preimage_limit;
|
|
|
|
|
if (preimage_limit < postimage->nr) {
|
|
|
|
|
nr = img->line_nr + postimage->line_nr - preimage_limit;
|
|
|
|
|
if (preimage_limit < postimage->line_nr)
|
|
|
|
|
/*
|
|
|
|
|
* NOTE: this knows that we never call remove_first_line()
|
|
|
|
|
* NOTE: this knows that we never call image_remove_first_line()
|
|
|
|
|
* on anything other than pre/post image.
|
|
|
|
|
*/
|
|
|
|
|
REALLOC_ARRAY(img->line, nr);
|
|
|
|
|
img->line_allocated = img->line;
|
|
|
|
|
}
|
|
|
|
|
if (preimage_limit != postimage->nr)
|
|
|
|
|
MOVE_ARRAY(img->line + applied_pos + postimage->nr,
|
|
|
|
|
if (preimage_limit != postimage->line_nr)
|
|
|
|
|
MOVE_ARRAY(img->line + applied_pos + postimage->line_nr,
|
|
|
|
|
img->line + applied_pos + preimage_limit,
|
|
|
|
|
img->nr - (applied_pos + preimage_limit));
|
|
|
|
|
COPY_ARRAY(img->line + applied_pos, postimage->line, postimage->nr);
|
|
|
|
|
img->line_nr - (applied_pos + preimage_limit));
|
|
|
|
|
COPY_ARRAY(img->line + applied_pos, postimage->line, postimage->line_nr);
|
|
|
|
|
if (!state->allow_overlap)
|
|
|
|
|
for (i = 0; i < postimage->nr; i++)
|
|
|
|
|
for (i = 0; i < postimage->line_nr; i++)
|
|
|
|
|
img->line[applied_pos + i].flag |= LINE_PATCHED;
|
|
|
|
|
img->nr = nr;
|
|
|
|
|
img->line_nr = nr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
@@ -2912,11 +2874,9 @@ static int apply_one_fragment(struct apply_state *state,
|
|
|
|
|
int hunk_linenr = frag->linenr;
|
|
|
|
|
unsigned long leading, trailing;
|
|
|
|
|
int pos, applied_pos;
|
|
|
|
|
struct image preimage;
|
|
|
|
|
struct image postimage;
|
|
|
|
|
struct image preimage = IMAGE_INIT;
|
|
|
|
|
struct image postimage = IMAGE_INIT;
|
|
|
|
|
|
|
|
|
|
memset(&preimage, 0, sizeof(preimage));
|
|
|
|
|
memset(&postimage, 0, sizeof(postimage));
|
|
|
|
|
oldlines = xmalloc(size);
|
|
|
|
|
strbuf_init(&newlines, size);
|
|
|
|
|
|
|
|
|
|
@@ -2958,8 +2918,8 @@ static int apply_one_fragment(struct apply_state *state,
|
|
|
|
|
break;
|
|
|
|
|
*old++ = '\n';
|
|
|
|
|
strbuf_addch(&newlines, '\n');
|
|
|
|
|
add_line_info(&preimage, "\n", 1, LINE_COMMON);
|
|
|
|
|
add_line_info(&postimage, "\n", 1, LINE_COMMON);
|
|
|
|
|
image_add_line(&preimage, "\n", 1, LINE_COMMON);
|
|
|
|
|
image_add_line(&postimage, "\n", 1, LINE_COMMON);
|
|
|
|
|
is_blank_context = 1;
|
|
|
|
|
break;
|
|
|
|
|
case ' ':
|
|
|
|
|
@@ -2969,7 +2929,7 @@ static int apply_one_fragment(struct apply_state *state,
|
|
|
|
|
/* fallthrough */
|
|
|
|
|
case '-':
|
|
|
|
|
memcpy(old, patch + 1, plen);
|
|
|
|
|
add_line_info(&preimage, old, plen,
|
|
|
|
|
image_add_line(&preimage, old, plen,
|
|
|
|
|
(first == ' ' ? LINE_COMMON : 0));
|
|
|
|
|
old += plen;
|
|
|
|
|
if (first == '-')
|
|
|
|
|
@@ -2989,7 +2949,7 @@ static int apply_one_fragment(struct apply_state *state,
|
|
|
|
|
else {
|
|
|
|
|
ws_fix_copy(&newlines, patch + 1, plen, ws_rule, &state->applied_after_fixing_ws);
|
|
|
|
|
}
|
|
|
|
|
add_line_info(&postimage, newlines.buf + start, newlines.len - start,
|
|
|
|
|
image_add_line(&postimage, newlines.buf + start, newlines.len - start,
|
|
|
|
|
(first == '+' ? 0 : LINE_COMMON));
|
|
|
|
|
if (first == '+' &&
|
|
|
|
|
(ws_rule & WS_BLANK_AT_EOF) &&
|
|
|
|
|
@@ -3023,8 +2983,8 @@ static int apply_one_fragment(struct apply_state *state,
|
|
|
|
|
newlines.len > 0 && newlines.buf[newlines.len - 1] == '\n') {
|
|
|
|
|
old--;
|
|
|
|
|
strbuf_setlen(&newlines, newlines.len - 1);
|
|
|
|
|
preimage.line_allocated[preimage.nr - 1].len--;
|
|
|
|
|
postimage.line_allocated[postimage.nr - 1].len--;
|
|
|
|
|
preimage.line[preimage.line_nr - 1].len--;
|
|
|
|
|
postimage.line[postimage.line_nr - 1].len--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
leading = frag->leading;
|
|
|
|
|
@@ -3054,12 +3014,8 @@ static int apply_one_fragment(struct apply_state *state,
|
|
|
|
|
match_end = !state->unidiff_zero && !trailing;
|
|
|
|
|
|
|
|
|
|
pos = frag->newpos ? (frag->newpos - 1) : 0;
|
|
|
|
|
preimage.buf = oldlines;
|
|
|
|
|
preimage.len = old - oldlines;
|
|
|
|
|
postimage.buf = newlines.buf;
|
|
|
|
|
postimage.len = newlines.len;
|
|
|
|
|
preimage.line = preimage.line_allocated;
|
|
|
|
|
postimage.line = postimage.line_allocated;
|
|
|
|
|
strbuf_add(&preimage.buf, oldlines, old - oldlines);
|
|
|
|
|
strbuf_swap(&postimage.buf, &newlines);
|
|
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
|
|
|
|
|
|
@@ -3083,28 +3039,28 @@ static int apply_one_fragment(struct apply_state *state,
|
|
|
|
|
* just reduce the larger context.
|
|
|
|
|
*/
|
|
|
|
|
if (leading >= trailing) {
|
|
|
|
|
remove_first_line(&preimage);
|
|
|
|
|
remove_first_line(&postimage);
|
|
|
|
|
image_remove_first_line(&preimage);
|
|
|
|
|
image_remove_first_line(&postimage);
|
|
|
|
|
pos--;
|
|
|
|
|
leading--;
|
|
|
|
|
}
|
|
|
|
|
if (trailing > leading) {
|
|
|
|
|
remove_last_line(&preimage);
|
|
|
|
|
remove_last_line(&postimage);
|
|
|
|
|
image_remove_last_line(&preimage);
|
|
|
|
|
image_remove_last_line(&postimage);
|
|
|
|
|
trailing--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (applied_pos >= 0) {
|
|
|
|
|
if (new_blank_lines_at_end &&
|
|
|
|
|
preimage.nr + applied_pos >= img->nr &&
|
|
|
|
|
preimage.line_nr + applied_pos >= img->line_nr &&
|
|
|
|
|
(ws_rule & WS_BLANK_AT_EOF) &&
|
|
|
|
|
state->ws_error_action != nowarn_ws_error) {
|
|
|
|
|
record_ws_error(state, WS_BLANK_AT_EOF, "+", 1,
|
|
|
|
|
found_new_blank_lines_at_end);
|
|
|
|
|
if (state->ws_error_action == correct_ws_error) {
|
|
|
|
|
while (new_blank_lines_at_end--)
|
|
|
|
|
remove_last_line(&postimage);
|
|
|
|
|
image_remove_last_line(&postimage);
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
* We would want to prevent write_out_results()
|
|
|
|
|
@@ -3147,8 +3103,8 @@ static int apply_one_fragment(struct apply_state *state,
|
|
|
|
|
out:
|
|
|
|
|
free(oldlines);
|
|
|
|
|
strbuf_release(&newlines);
|
|
|
|
|
free(preimage.line_allocated);
|
|
|
|
|
free(postimage.line_allocated);
|
|
|
|
|
image_clear(&preimage);
|
|
|
|
|
image_clear(&postimage);
|
|
|
|
|
|
|
|
|
|
return (applied_pos < 0);
|
|
|
|
|
}
|
|
|
|
|
@@ -3178,18 +3134,16 @@ static int apply_binary_fragment(struct apply_state *state,
|
|
|
|
|
}
|
|
|
|
|
switch (fragment->binary_patch_method) {
|
|
|
|
|
case BINARY_DELTA_DEFLATED:
|
|
|
|
|
dst = patch_delta(img->buf, img->len, fragment->patch,
|
|
|
|
|
dst = patch_delta(img->buf.buf, img->buf.len, fragment->patch,
|
|
|
|
|
fragment->size, &len);
|
|
|
|
|
if (!dst)
|
|
|
|
|
return -1;
|
|
|
|
|
clear_image(img);
|
|
|
|
|
img->buf = dst;
|
|
|
|
|
img->len = len;
|
|
|
|
|
image_clear(img);
|
|
|
|
|
strbuf_attach(&img->buf, dst, len, len + 1);
|
|
|
|
|
return 0;
|
|
|
|
|
case BINARY_LITERAL_DEFLATED:
|
|
|
|
|
clear_image(img);
|
|
|
|
|
img->len = fragment->size;
|
|
|
|
|
img->buf = xmemdupz(fragment->patch, img->len);
|
|
|
|
|
image_clear(img);
|
|
|
|
|
strbuf_add(&img->buf, fragment->patch, fragment->size);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
@@ -3225,8 +3179,8 @@ static int apply_binary(struct apply_state *state,
|
|
|
|
|
* See if the old one matches what the patch
|
|
|
|
|
* applies to.
|
|
|
|
|
*/
|
|
|
|
|
hash_object_file(the_hash_algo, img->buf, img->len, OBJ_BLOB,
|
|
|
|
|
&oid);
|
|
|
|
|
hash_object_file(the_hash_algo, img->buf.buf, img->buf.len,
|
|
|
|
|
OBJ_BLOB, &oid);
|
|
|
|
|
if (strcmp(oid_to_hex(&oid), patch->old_oid_prefix))
|
|
|
|
|
return error(_("the patch applies to '%s' (%s), "
|
|
|
|
|
"which does not match the "
|
|
|
|
|
@@ -3235,14 +3189,14 @@ static int apply_binary(struct apply_state *state,
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Otherwise, the old one must be empty. */
|
|
|
|
|
if (img->len)
|
|
|
|
|
if (img->buf.len)
|
|
|
|
|
return error(_("the patch applies to an empty "
|
|
|
|
|
"'%s' but it is not empty"), name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get_oid_hex(patch->new_oid_prefix, &oid);
|
|
|
|
|
if (is_null_oid(&oid)) {
|
|
|
|
|
clear_image(img);
|
|
|
|
|
image_clear(img);
|
|
|
|
|
return 0; /* deletion patch */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -3258,9 +3212,8 @@ static int apply_binary(struct apply_state *state,
|
|
|
|
|
return error(_("the necessary postimage %s for "
|
|
|
|
|
"'%s' cannot be read"),
|
|
|
|
|
patch->new_oid_prefix, name);
|
|
|
|
|
clear_image(img);
|
|
|
|
|
img->buf = result;
|
|
|
|
|
img->len = size;
|
|
|
|
|
image_clear(img);
|
|
|
|
|
strbuf_attach(&img->buf, result, size, size + 1);
|
|
|
|
|
} else {
|
|
|
|
|
/*
|
|
|
|
|
* We have verified buf matches the preimage;
|
|
|
|
|
@@ -3272,7 +3225,7 @@ static int apply_binary(struct apply_state *state,
|
|
|
|
|
name);
|
|
|
|
|
|
|
|
|
|
/* verify that the result matches */
|
|
|
|
|
hash_object_file(the_hash_algo, img->buf, img->len, OBJ_BLOB,
|
|
|
|
|
hash_object_file(the_hash_algo, img->buf.buf, img->buf.len, OBJ_BLOB,
|
|
|
|
|
&oid);
|
|
|
|
|
if (strcmp(oid_to_hex(&oid), patch->new_oid_prefix))
|
|
|
|
|
return error(_("binary patch to '%s' creates incorrect result (expecting %s, got %s)"),
|
|
|
|
|
@@ -3534,7 +3487,7 @@ static int load_preimage(struct apply_state *state,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
img = strbuf_detach(&buf, &len);
|
|
|
|
|
prepare_image(image, img, len, !patch->is_binary);
|
|
|
|
|
image_prepare(image, img, len, !patch->is_binary);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -3542,14 +3495,14 @@ static int resolve_to(struct image *image, const struct object_id *result_id)
|
|
|
|
|
{
|
|
|
|
|
unsigned long size;
|
|
|
|
|
enum object_type type;
|
|
|
|
|
char *data;
|
|
|
|
|
|
|
|
|
|
clear_image(image);
|
|
|
|
|
image_clear(image);
|
|
|
|
|
|
|
|
|
|
image->buf = repo_read_object_file(the_repository, result_id, &type,
|
|
|
|
|
&size);
|
|
|
|
|
if (!image->buf || type != OBJ_BLOB)
|
|
|
|
|
data = repo_read_object_file(the_repository, result_id, &type, &size);
|
|
|
|
|
if (!data || type != OBJ_BLOB)
|
|
|
|
|
die("unable to read blob object %s", oid_to_hex(result_id));
|
|
|
|
|
image->len = size;
|
|
|
|
|
strbuf_attach(&image->buf, data, size, size + 1);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
@@ -3592,9 +3545,8 @@ static int three_way_merge(struct apply_state *state,
|
|
|
|
|
free(result.ptr);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
clear_image(image);
|
|
|
|
|
image->buf = result.ptr;
|
|
|
|
|
image->len = result.size;
|
|
|
|
|
image_clear(image);
|
|
|
|
|
strbuf_attach(&image->buf, result.ptr, result.size, result.size);
|
|
|
|
|
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
@@ -3639,7 +3591,7 @@ static int load_current(struct apply_state *state,
|
|
|
|
|
else if (status)
|
|
|
|
|
return -1;
|
|
|
|
|
img = strbuf_detach(&buf, &len);
|
|
|
|
|
prepare_image(image, img, len, !patch->is_binary);
|
|
|
|
|
image_prepare(image, img, len, !patch->is_binary);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -3654,7 +3606,7 @@ static int try_threeway(struct apply_state *state,
|
|
|
|
|
size_t len;
|
|
|
|
|
int status;
|
|
|
|
|
char *img;
|
|
|
|
|
struct image tmp_image;
|
|
|
|
|
struct image tmp_image = IMAGE_INIT;
|
|
|
|
|
|
|
|
|
|
/* No point falling back to 3-way merge in these cases */
|
|
|
|
|
if (patch->is_delete ||
|
|
|
|
|
@@ -3674,15 +3626,15 @@ static int try_threeway(struct apply_state *state,
|
|
|
|
|
fprintf(stderr, _("Performing three-way merge...\n"));
|
|
|
|
|
|
|
|
|
|
img = strbuf_detach(&buf, &len);
|
|
|
|
|
prepare_image(&tmp_image, img, len, 1);
|
|
|
|
|
image_prepare(&tmp_image, img, len, 1);
|
|
|
|
|
/* Apply the patch to get the post image */
|
|
|
|
|
if (apply_fragments(state, &tmp_image, patch) < 0) {
|
|
|
|
|
clear_image(&tmp_image);
|
|
|
|
|
image_clear(&tmp_image);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
/* post_oid is theirs */
|
|
|
|
|
write_object_file(tmp_image.buf, tmp_image.len, OBJ_BLOB, &post_oid);
|
|
|
|
|
clear_image(&tmp_image);
|
|
|
|
|
write_object_file(tmp_image.buf.buf, tmp_image.buf.len, OBJ_BLOB, &post_oid);
|
|
|
|
|
image_clear(&tmp_image);
|
|
|
|
|
|
|
|
|
|
/* our_oid is ours */
|
|
|
|
|
if (patch->is_new) {
|
|
|
|
|
@@ -3694,8 +3646,8 @@ static int try_threeway(struct apply_state *state,
|
|
|
|
|
return error(_("cannot read the current contents of '%s'"),
|
|
|
|
|
patch->old_name);
|
|
|
|
|
}
|
|
|
|
|
write_object_file(tmp_image.buf, tmp_image.len, OBJ_BLOB, &our_oid);
|
|
|
|
|
clear_image(&tmp_image);
|
|
|
|
|
write_object_file(tmp_image.buf.buf, tmp_image.buf.len, OBJ_BLOB, &our_oid);
|
|
|
|
|
image_clear(&tmp_image);
|
|
|
|
|
|
|
|
|
|
/* in-core three-way merge between post and our using pre as base */
|
|
|
|
|
status = three_way_merge(state, image, patch->new_name,
|
|
|
|
|
@@ -3731,7 +3683,7 @@ static int try_threeway(struct apply_state *state,
|
|
|
|
|
static int apply_data(struct apply_state *state, struct patch *patch,
|
|
|
|
|
struct stat *st, const struct cache_entry *ce)
|
|
|
|
|
{
|
|
|
|
|
struct image image;
|
|
|
|
|
struct image image = IMAGE_INIT;
|
|
|
|
|
|
|
|
|
|
if (load_preimage(state, &image, patch, st, ce) < 0)
|
|
|
|
|
return -1;
|
|
|
|
|
@@ -3743,14 +3695,13 @@ static int apply_data(struct apply_state *state, struct patch *patch,
|
|
|
|
|
|
|
|
|
|
/* Note: with --reject, apply_fragments() returns 0 */
|
|
|
|
|
if (patch->direct_to_threeway || apply_fragments(state, &image, patch) < 0) {
|
|
|
|
|
clear_image(&image);
|
|
|
|
|
image_clear(&image);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
patch->result = image.buf;
|
|
|
|
|
patch->resultsize = image.len;
|
|
|
|
|
patch->result = strbuf_detach(&image.buf, &patch->resultsize);
|
|
|
|
|
add_to_fn_table(state, patch);
|
|
|
|
|
free(image.line_allocated);
|
|
|
|
|
free(image.line);
|
|
|
|
|
|
|
|
|
|
if (0 < patch->is_delete && patch->resultsize)
|
|
|
|
|
return error(_("removal patch leaves file contents"));
|
|
|
|
|
|