upload-pack: use buffered I/O to talk to rev-list
Like f0bca72dc77 (send-pack: use buffered I/O to talk to pack-objects, 2016-06-08), significantly reduce the number of system calls and simplify the code for sending object IDs to rev-list by using stdio's buffering. Take care to handle errors immediately to get the correct error code, and to flush the buffer explicitly before closing the stream in order to catch any write errors for these last bytes. Helped-by: Chris Torek <chris.torek@gmail.com> Helped-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
René Scharfe committed
Aug 12, 2020 at 18:52 UTC
a698d67b08f98ddac0e6df898fbfab5b4fbd36b1
1 file changed
+10
-12
upload-pack.c
+10
-12
@@ -595,9 +595,8 @@ static int do_reachable_revlist(struct child_process *cmd,
595
"rev-list", "--stdin", NULL,
596
};
597
struct object *o;
598
- char namebuf[GIT_MAX_HEXSZ + 2]; /* ^ + hash + LF */
598
+ FILE *cmd_in = NULL;
599
int i;
600
- const unsigned hexsz = the_hash_algo->hexsz;
600
601
cmd->argv = argv;
602
cmd->git_cmd = 1;
@@ -615,8 +614,8 @@ static int do_reachable_revlist(struct child_process *cmd,
614
if (start_command(cmd))
615
goto error;
616
618
- namebuf[0] = '^';
619
- namebuf[hexsz + 1] = '\n';
617
+ cmd_in = xfdopen(cmd->in, "w");
618
+
619
for (i = get_max_object_index(); 0 < i; ) {
620
o = get_indexed_object(--i);
621
if (!o)
@@ -625,11 +624,9 @@ static int do_reachable_revlist(struct child_process *cmd,
624
o->flags &= ~TMP_MARK;
625
if (!is_our_ref(o, allow_uor))
626
continue;
628
- memcpy(namebuf + 1, oid_to_hex(&o->oid), hexsz);
629
- if (write_in_full(cmd->in, namebuf, hexsz + 2) < 0)
627
+ if (fprintf(cmd_in, "^%s\n", oid_to_hex(&o->oid)) < 0)
628
goto error;
629
}
632
- namebuf[hexsz] = '\n';
630
for (i = 0; i < src->nr; i++) {
631
o = src->objects[i].item;
632
if (is_our_ref(o, allow_uor)) {
@@ -639,11 +636,12 @@ static int do_reachable_revlist(struct child_process *cmd,
636
}
637
if (reachable && o->type == OBJ_COMMIT)
638
o->flags |= TMP_MARK;
642
- memcpy(namebuf, oid_to_hex(&o->oid), hexsz);
643
- if (write_in_full(cmd->in, namebuf, hexsz + 1) < 0)
639
+ if (fprintf(cmd_in, "%s\n", oid_to_hex(&o->oid)) < 0)
640
goto error;
641
}
646
- close(cmd->in);
642
+ if (ferror(cmd_in) || fflush(cmd_in))
643
+ goto error;
644
+ fclose(cmd_in);
645
cmd->in = -1;
646
sigchain_pop(SIGPIPE);
647
@@ -652,8 +650,8 @@ static int do_reachable_revlist(struct child_process *cmd,
650
error:
651
sigchain_pop(SIGPIPE);
652
655
- if (cmd->in >= 0)
656
- close(cmd->in);
653
+ if (cmd_in)
654
+ fclose(cmd_in);
655
if (cmd->out >= 0)
656
close(cmd->out);
657
return -1;