@matheusbsbs / matheus-bagliano / commits / 49bee717f7
Fork 0

upload-pack: More aggressively send 'ACK %s ready'

If a client is merely following the remote (and has not made any new commits itself), all "have %s" lines sent by the client will be common to the server. As all lines are common upload-pack never calls ok_to_give_up() and does not compute if it has a good cut point in the commit graph. Without this computation the following client is going to send all tagged commits, as these were determined to be COMMON_REF during the initial advertisement, but the client does not parse their history to transitively pass the COMMON flag and empty its queue of commits. For git.git with 339 commit tags, it takes clients 11 rounds of negotation to fully send all tagged commits and exhaust its queue of things to send as common. This is pretty slow for a client that has not done any local development activity. Force computing ok_to_give_up() and send "ACK %s ready" at the end of the current round if this round only contained common objects and ok_to_give_up() was therefore not called. This may allow the client to break early, avoiding transmission of the COMMON_REFs. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Shawn O. Pearce committed Mar 14, 2011 at 16:48 UTC 49bee717f7080f99d3405682cc43ad525dde0973
1 file changed +9
upload-pack.c
+9
@@ -429,6 +429,8 @@ static int get_common_commits(void)
429 static char line[1000];
430 unsigned char sha1[20];
431 char last_hex[41];
432 + int got_common = 0;
433 + int got_other = 0;
434
435 save_commit_buffer = 0;
436
@@ -437,16 +439,22 @@ static int get_common_commits(void)
439 reset_timeout();
440
441 if (!len) {
442 + if (multi_ack == 2 && got_common
443 + && !got_other && ok_to_give_up())
444 + packet_write(1, "ACK %s ready\n", last_hex);
445 if (have_obj.nr == 0 || multi_ack)
446 packet_write(1, "NAK\n");
447 if (stateless_rpc)
448 exit(0);
449 + got_common = 0;
450 + got_other = 0;
451 continue;
452 }
453 strip(line, len);
454 if (!prefixcmp(line, "have ")) {
455 switch (got_sha1(line+5, sha1)) {
456 case -1: /* they have what we do not */
457 + got_other = 1;
458 if (multi_ack && ok_to_give_up()) {
459 const char *hex = sha1_to_hex(sha1);
460 if (multi_ack == 2)
@@ -456,6 +464,7 @@ static int get_common_commits(void)
464 }
465 break;
466 default:
467 + got_common = 1;
468 memcpy(last_hex, sha1_to_hex(sha1), 41);
469 if (multi_ack == 2)
470 packet_write(1, "ACK %s common\n", last_hex);