builtin-apply.c: mark common context lines in lineinfo structure.
This updates the way preimage and postimage in a patch hunk is parsed and prepared for applying. By looking at image->line[n].flag, the code can tell if it is a common context line that is the same between the preimage and the postimage. This matters when we actually start applying a patch with contexts that have whitespace breakages that have already been fixed in the target file.
Junio C Hamano committed
Jan 29, 2008 at 00:17 UTC
c330fdd42dc57127272534cd2a8dd9569334b219
1 file changed
+32
-25
builtin-apply.c
+32
-25
@@ -170,6 +170,7 @@ struct line {
170
size_t len;
171
unsigned hash : 24;
172
unsigned flag : 8;
173
+#define LINE_COMMON 1
174
};
175
176
/*
@@ -179,6 +180,7 @@ struct image {
180
char *buf;
181
size_t len;
182
size_t nr;
183
+ size_t alloc;
184
struct line *line_allocated;
185
struct line *line;
186
};
@@ -195,49 +197,39 @@ static uint32_t hash_line(const char *cp, size_t len)
197
return h;
198
}
199
200
+static void add_line_info(struct image *img, const char *bol, size_t len, unsigned flag)
201
+{
202
+ ALLOC_GROW(img->line_allocated, img->nr + 1, img->alloc);
203
+ img->line_allocated[img->nr].len = len;
204
+ img->line_allocated[img->nr].hash = hash_line(bol, len);
205
+ img->line_allocated[img->nr].flag = flag;
206
+ img->nr++;
207
+}
208
+
209
static void prepare_image(struct image *image, char *buf, size_t len,
210
int prepare_linetable)
211
{
212
const char *cp, *ep;
202
- int n;
213
214
+ memset(image, 0, sizeof(*image));
215
image->buf = buf;
216
image->len = len;
217
207
- if (!prepare_linetable) {
208
- image->line = NULL;
209
- image->line_allocated = NULL;
210
- image->nr = 0;
218
+ if (!prepare_linetable)
219
return;
212
- }
220
221
ep = image->buf + image->len;
215
-
216
- /* First count lines */
222
cp = image->buf;
218
- n = 0;
219
- while (cp < ep) {
220
- cp = strchrnul(cp, '\n');
221
- n++;
222
- cp++;
223
- }
224
-
225
- image->line_allocated = xcalloc(n, sizeof(struct line));
226
- image->line = image->line_allocated;
227
- image->nr = n;
228
- cp = image->buf;
229
- n = 0;
223
while (cp < ep) {
224
const char *next;
225
for (next = cp; next < ep && *next != '\n'; next++)
226
;
227
if (next < ep)
228
next++;
236
- image->line[n].len = next - cp;
237
- image->line[n].hash = hash_line(cp, next - cp);
229
+ add_line_info(image, cp, next - cp, 0);
230
cp = next;
239
- n++;
231
}
232
+ image->line = image->line_allocated;
233
}
234
235
static void clear_image(struct image *image)
@@ -1822,6 +1814,9 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
1814
struct image preimage;
1815
struct image postimage;
1816
1817
+ memset(&preimage, 0, sizeof(preimage));
1818
+ memset(&postimage, 0, sizeof(postimage));
1819
+
1820
while (size > 0) {
1821
char first;
1822
int len = linelen(patch, size);
@@ -1857,10 +1852,14 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
1852
break;
1853
old[oldsize++] = '\n';
1854
new[newsize++] = '\n';
1855
+ add_line_info(&preimage, "\n", 1, LINE_COMMON);
1856
+ add_line_info(&postimage, "\n", 1, LINE_COMMON);
1857
break;
1858
case ' ':
1859
case '-':
1860
memcpy(old + oldsize, patch + 1, plen);
1861
+ add_line_info(&preimage, old + oldsize, plen,
1862
+ (first == ' ' ? LINE_COMMON : 0));
1863
oldsize += plen;
1864
if (first == '-')
1865
break;
@@ -1869,6 +1868,9 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
1868
if (first != '+' || !no_add) {
1869
int added = apply_line(new + newsize, patch,
1870
plen, ws_rule);
1871
+ add_line_info(&postimage, new + newsize, added,
1872
+ (first == '+' ? 0 : LINE_COMMON));
1873
+
1874
newsize += added;
1875
if (first == '+' &&
1876
added == 1 && new[newsize-1] == '\n')
@@ -1921,8 +1923,13 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
1923
}
1924
1925
pos = frag->newpos ? (frag->newpos - 1) : 0;
1924
- prepare_image(&preimage, oldlines, oldsize, 1);
1925
- prepare_image(&postimage, newlines, newsize, 1);
1926
+ preimage.buf = old;
1927
+ preimage.len = oldsize;
1928
+ postimage.buf = new;
1929
+ postimage.len = newsize;
1930
+ preimage.line = preimage.line_allocated;
1931
+ postimage.line = postimage.line_allocated;
1932
+
1933
for (;;) {
1934
1935
applied_pos = find_pos(img, &preimage, &postimage,