Skip to content

Commit 407a792

Browse files
committed
apply: count the size of postimage correctly
Under --whitespace=fix option, match_fragment() function examines the preimage (the common context and the removed lines in the patch) and the file being patched and checks if they match after correcting all whitespace errors. When they are found to match, the common context lines in the preimage is replaced with the fixed copy, because these lines will then be copied to the corresponding place in the postimage by a later call to update_pre_post_images(). Lines that are added in the postimage, under --whitespace=fix, have their whitespace errors already fixed when apply_one_fragment() prepares the preimage and the postimage, so in the end, application of the patch can be done by replacing the block of text in the file being patched that matched the preimage with what is in the postimage that was updated by update_pre_post_images(). In the earlier days, fixing whitespace errors always resulted in reduction of size, either collapsing runs of spaces in the indent to a tab or removing the trailing whitespaces. These days, however, some whitespace error fix results in extending the size. 250b3c6 (apply --whitespace=fix: avoid running over the postimage buffer, 2013-03-22) tried to compute the final postimage size but its math was flawed. It counted the size of the block of text in the original being patched after fixing the whitespace errors on its lines that correspond to the preimage. That number does not have much to do with how big the final postimage would be. Instead count (1) the added lines in the postimage, whose size is the same as in the final patch result because their whitespace errors have already been corrected, and (2) the fixed size of the lines that are common. Signed-off-by: Junio C Hamano <[email protected]>
1 parent 2988289 commit 407a792

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

builtin/apply.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2336,14 +2336,30 @@ static int match_fragment(struct image *img,
23362336
* ignore whitespace, we were asked to correct whitespace
23372337
* errors, so let's try matching after whitespace correction.
23382338
*
2339+
* While checking the preimage against the target, whitespace
2340+
* errors in both fixed, we count how large the corresponding
2341+
* postimage needs to be. The postimage prepared by
2342+
* apply_one_fragment() has whitespace errors fixed on added
2343+
* lines already, but the common lines were propagated as-is,
2344+
* which may become longer when their whitespace errors are
2345+
* fixed.
2346+
*/
2347+
2348+
/* First count added lines in postimage */
2349+
postlen = 0;
2350+
for (i = 0; i < postimage->nr; i++) {
2351+
if (!(postimage->line[i].flag & LINE_COMMON))
2352+
postlen += postimage->line[i].len;
2353+
}
2354+
2355+
/*
23392356
* The preimage may extend beyond the end of the file,
23402357
* but in this loop we will only handle the part of the
23412358
* preimage that falls within the file.
23422359
*/
23432360
strbuf_init(&fixed, preimage->len + 1);
23442361
orig = preimage->buf;
23452362
target = img->buf + try;
2346-
postlen = 0;
23472363
for (i = 0; i < preimage_limit; i++) {
23482364
size_t oldlen = preimage->line[i].len;
23492365
size_t tgtlen = img->line[try_lno + i].len;
@@ -2371,7 +2387,10 @@ static int match_fragment(struct image *img,
23712387
match = (tgtfix.len == fixed.len - fixstart &&
23722388
!memcmp(tgtfix.buf, fixed.buf + fixstart,
23732389
fixed.len - fixstart));
2374-
postlen += tgtfix.len;
2390+
2391+
/* Add the length if this is common with the postimage */
2392+
if (preimage->line[i].flag & LINE_COMMON)
2393+
postlen += tgtfix.len;
23752394

23762395
strbuf_release(&tgtfix);
23772396
if (!match)

0 commit comments

Comments
 (0)