path: root/write_or_die.c
diff options
authorJeff King <>2014-09-10 10:03:52 (GMT)
committerJunio C Hamano <>2014-09-10 17:58:32 (GMT)
commit9540ce5030853ffbb7e11c30aa59a5e45095d32c (patch)
treedaaa9507ddd96312a5c41708d3554ccf5cf0169b /write_or_die.c
parent0c72b98f31bf6eabd75be565a08ffcf0d8e74b1f (diff)
refs: write packed_refs file using stdio
We write each line of a new packed-refs file individually using a write() syscall (and sometimes 2, if the ref is peeled). Since each line is only about 50-100 bytes long, this creates a lot of system call overhead. We can instead open a stdio handle around our descriptor and use fprintf to write to it. The extra buffering is not a problem for us, because nobody will read our new packed-refs file until we call commit_lock_file (by which point we have flushed everything). On a pathological repository with 8.5 million refs, this dropped the time to run `git pack-refs` from 20s to 6s. Signed-off-by: Jeff King <> Reviewed-by: Michael Haggerty <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'write_or_die.c')
1 files changed, 15 insertions, 0 deletions
diff --git a/write_or_die.c b/write_or_die.c
index b50f99a..e7afe7a 100644
--- a/write_or_die.c
+++ b/write_or_die.c
@@ -49,6 +49,21 @@ void maybe_flush_or_die(FILE *f, const char *desc)
+void fprintf_or_die(FILE *f, const char *fmt, ...)
+ va_list ap;
+ int ret;
+ va_start(ap, fmt);
+ ret = vfprintf(f, fmt, ap);
+ va_end(ap);
+ if (ret < 0) {
+ check_pipe(errno);
+ die_errno("write error");
+ }
void fsync_or_die(int fd, const char *msg)
if (fsync(fd) < 0) {