rerere: return strbuf from handle path
Currently we write the conflict to disk directly in the handle_path function. To make it re-usable for nested conflicts, instead of writing the conflict out directly, store it in a strbuf and let the caller write it out. This does mean some slight increase in memory usage, however that increase is limited to the size of the largest conflict we've currently processed. We already keep one copy of the conflict in memory, and it shouldn't be too large, so the increase in memory usage seems acceptable. As a bonus this lets us get replace the rerere_io_putconflict function with a trivial two line function. Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Thomas Gummerer committed
Aug 5, 2018 at 18:20 UTC
5ebbdad3447ccaaf5af18a5f4f8f5065bd9fff3d
1 file changed
+18
-40
rerere.c
+18
-40
@@ -302,38 +302,6 @@ static void rerere_io_putstr(const char *str, struct rerere_io *io)
302
ferr_puts(str, io->output, &io->wrerror);
303
}
304
305
-/*
306
- * Write a conflict marker to io->output (if defined).
307
- */
308
-static void rerere_io_putconflict(int ch, int size, struct rerere_io *io)
309
-{
310
- char buf[64];
311
-
312
- while (size) {
313
- if (size <= sizeof(buf) - 2) {
314
- memset(buf, ch, size);
315
- buf[size] = '\n';
316
- buf[size + 1] = '\0';
317
- size = 0;
318
- } else {
319
- int sz = sizeof(buf) - 1;
320
-
321
- /*
322
- * Make sure we will not write everything out
323
- * in this round by leaving at least 1 byte
324
- * for the next round, giving the next round
325
- * a chance to add the terminating LF. Yuck.
326
- */
327
- if (size <= sz)
328
- sz -= (sz - size) + 1;
329
- memset(buf, ch, sz);
330
- buf[sz] = '\0';
331
- size -= sz;
332
- }
333
- rerere_io_putstr(buf, io);
334
- }
335
-}
336
-
305
static void rerere_io_putmem(const char *mem, size_t sz, struct rerere_io *io)
306
{
307
if (io->output)
@@ -384,7 +352,14 @@ static int is_cmarker(char *buf, int marker_char, int marker_size)
352
return isspace(*buf);
353
}
354
387
-static int handle_conflict(struct rerere_io *io, int marker_size, git_SHA_CTX *ctx)
355
+static void rerere_strbuf_putconflict(struct strbuf *buf, int ch, size_t size)
356
+{
357
+ strbuf_addchars(buf, ch, size);
358
+ strbuf_addch(buf, '\n');
359
+}
360
+
361
+static int handle_conflict(struct strbuf *out, struct rerere_io *io,
362
+ int marker_size, git_SHA_CTX *ctx)
363
{
364
enum {
365
RR_SIDE_1 = 0, RR_SIDE_2, RR_ORIGINAL
@@ -410,11 +385,11 @@ static int handle_conflict(struct rerere_io *io, int marker_size, git_SHA_CTX *c
385
if (strbuf_cmp(&one, &two) > 0)
386
strbuf_swap(&one, &two);
387
has_conflicts = 1;
413
- rerere_io_putconflict('<', marker_size, io);
414
- rerere_io_putmem(one.buf, one.len, io);
415
- rerere_io_putconflict('=', marker_size, io);
416
- rerere_io_putmem(two.buf, two.len, io);
417
- rerere_io_putconflict('>', marker_size, io);
388
+ rerere_strbuf_putconflict(out, '<', marker_size);
389
+ strbuf_addbuf(out, &one);
390
+ rerere_strbuf_putconflict(out, '=', marker_size);
391
+ strbuf_addbuf(out, &two);
392
+ rerere_strbuf_putconflict(out, '>', marker_size);
393
if (ctx) {
394
git_SHA1_Update(ctx, one.buf ? one.buf : "",
395
one.len + 1);
@@ -451,21 +426,24 @@ static int handle_conflict(struct rerere_io *io, int marker_size, git_SHA_CTX *c
426
static int handle_path(unsigned char *sha1, struct rerere_io *io, int marker_size)
427
{
428
git_SHA_CTX ctx;
454
- struct strbuf buf = STRBUF_INIT;
429
+ struct strbuf buf = STRBUF_INIT, out = STRBUF_INIT;
430
int has_conflicts = 0;
431
if (sha1)
432
git_SHA1_Init(&ctx);
433
434
while (!io->getline(&buf, io)) {
435
if (is_cmarker(buf.buf, '<', marker_size)) {
461
- has_conflicts = handle_conflict(io, marker_size,
436
+ has_conflicts = handle_conflict(&out, io, marker_size,
437
sha1 ? &ctx : NULL);
438
if (has_conflicts < 0)
439
break;
440
+ rerere_io_putmem(out.buf, out.len, io);
441
+ strbuf_reset(&out);
442
} else
443
rerere_io_putstr(buf.buf, io);
444
}
445
strbuf_release(&buf);
446
+ strbuf_release(&out);
447
448
if (sha1)
449
git_SHA1_Final(sha1, &ctx);