This patch does not change the results (nor any of the semantics except for the get_rev return type), but we need the changed layout for the exponential-stride feature. Signed-off-by: Thomas Rast <trast@xxxxxxxxxxxxxxx> --- builtin-fetch-pack.c | 108 +++++++++++++++++++++++++++++-------------------- 1 files changed, 64 insertions(+), 44 deletions(-) diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c index 372bfa2..ae0a67a 100644 --- a/builtin-fetch-pack.c +++ b/builtin-fetch-pack.c @@ -111,7 +111,7 @@ static void mark_common(struct commit *commit, Get the next rev to send, ignoring the common. */ -static const unsigned char* get_rev(void) +static struct commit* get_rev(void) { struct commit *commit = NULL; @@ -153,15 +153,41 @@ static void mark_common(struct commit *commit, rev_list = rev_list->next; } - return commit->object.sha1; + return commit; } +/* + * Send 'have' for the next batch of revisions. Returns 0 if we ran + * out of commits to send, 1 otherwise. + */ + +static int send_have_lines(int fd[2], int *flushes, unsigned *in_vain) +{ + struct commit *commit; + int i; + + for (i = 0; i < 32; i++) { + commit = get_rev(); + if (!commit) + return 0; + packet_write(fd[1], "have %s\n", + sha1_to_hex(commit->object.sha1)); + if (args.verbose) + fprintf(stderr, "have %s\n", + sha1_to_hex(commit->object.sha1)); + } + packet_flush(fd[1]); + *flushes += 1; + *in_vain += 32; + return 1; +} + + static int find_common(int fd[2], unsigned char *result_sha1, struct ref *refs) { int fetching; int count = 0, flushes = 0, retval; - const unsigned char *sha1; unsigned in_vain = 0; int got_continue = 0; @@ -243,51 +269,45 @@ static int find_common(int fd[2], unsigned char *result_sha1, flushes = 0; retval = -1; - while ((sha1 = get_rev())) { - packet_write(fd[1], "have %s\n", sha1_to_hex(sha1)); - if (args.verbose) - fprintf(stderr, "have %s\n", sha1_to_hex(sha1)); - in_vain++; - if (!(31 & ++count)) { - int ack; - packet_flush(fd[1]); - flushes++; + /* + * We keep one window "ahead" of the other side, and + * will wait for an ACK only on the next one + */ + if (!send_have_lines(fd, &flushes, &in_vain)) + goto done; - /* - * We keep one window "ahead" of the other side, and - * will wait for an ACK only on the next one - */ - if (count == 32) - continue; + while (send_have_lines(fd, &flushes, &in_vain)) { + int ack; + int unwound = 0; - do { - ack = get_ack(fd[0], result_sha1); - if (args.verbose && ack) - fprintf(stderr, "got ack %d %s\n", ack, - sha1_to_hex(result_sha1)); - if (ack == 1) { - flushes = 0; - multi_ack = 0; - retval = 0; - goto done; - } else if (ack == 2) { - struct commit *commit = - lookup_commit(result_sha1); - mark_common(commit, 0, 1); - retval = 0; - in_vain = 0; - got_continue = 1; - } - } while (ack); - flushes--; - if (got_continue && MAX_IN_VAIN < in_vain) { - if (args.verbose) - fprintf(stderr, "giving up\n"); - break; /* give up */ + do { + ack = get_ack(fd[0], result_sha1); + if (args.verbose && ack) + fprintf(stderr, "got ack %d %s\n", ack, + sha1_to_hex(result_sha1)); + if (ack == 1) { + flushes = 0; + multi_ack = 0; + retval = 0; + goto done; + } else if (ack == 2) { + struct commit *commit = + lookup_commit(result_sha1); + mark_common(commit, 0, 1); + retval = 0; + in_vain = 0; + got_continue = 1; } + } while (ack); + flushes--; + if (got_continue && MAX_IN_VAIN < in_vain) { + if (args.verbose) + fprintf(stderr, "giving up\n"); + break; /* give up */ } } + done: packet_write(fd[1], "done\n"); if (args.verbose) -- tg: (7f705dc..) t/fp-refactor (depends on: origin/master) -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html