[PATCH v2 1/3] merge-ll: use strbuf to read back external merge result
flat view
COOLING13d
From: Jeff King <hidden>
Date: 2026-09-11 17:11:26
Subsystem:
the rest · Maintainer:
Linus Torvalds
After the external merge runs, we read the file back into a heap buffer.
This ancient code does it by hand, but these days we can make the code
shorter and less error prone by using strbuf_read_file().
It's not quite a one-liner replacement, because we have to copy the
pointer and size into an mmbuffer_t. Two things to note there:
1. We can't just pass result->size to strbuf_detach(), since the
former uses long instead of size_t (something that we'd ideally fix
in the long run, but is way out of scope here).
2. We can leave result untouched on error; we zero it at the top of
the function (confusingly we may still return LL_MERGE_OK and a
NULL result if we hit an I/O error, but that is how the function
has always behaved, and callers know to check for NULL).
Signed-off-by: Jeff King <redacted>
---
Not strictly needed for the rest of the series, but it felt like a
cleanup worth doing, and it conflicts textually.
merge-ll.c | 22 +++++++---------------
1 file changed, 7 insertions(+), 15 deletions(-)
diff --git a/merge-ll.c b/merge-ll.c
index ef5287dee8..5b6af15e23 100644
--- a/merge-ll.c
+++ b/merge-ll.c@@ -201,8 +201,8 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn, struct strbuf cmd = STRBUF_INIT; const char *format = fn->cmdline; struct child_process child = CHILD_PROCESS_INIT; - int status, fd, i; - struct stat st; + int status, i; + struct strbuf result_buf = STRBUF_INIT; enum ll_merge_result ret; assert(opts);
@@ -241,20 +241,12 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn, child.use_shell = 1; strvec_push(&child.args, cmd.buf); status = run_command(&child); - fd = open(temp[1], O_RDONLY); - if (fd < 0) - goto bad; - if (fstat(fd, &st)) - goto close_bad; - result->size = st.st_size; - result->ptr = xmallocz(result->size); - if (read_in_full(fd, result->ptr, result->size) != result->size) { - FREE_AND_NULL(result->ptr); - result->size = 0; + + if (strbuf_read_file(&result_buf, temp[1], 0) >= 0) { + result->size = result_buf.len; + result->ptr = strbuf_detach(&result_buf, NULL); } - close_bad: - close(fd); - bad: + for (i = 0; i < 3; i++) unlink_or_warn(temp[i]); strbuf_release(&cmd);
--
2.56.0.rc0.314.g7a874b6915