summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 7ed863a)
raw | patch | inline | side by side (parent: 7ed863a)
author | Shawn O. Pearce <spearce@spearce.org> | |
Mon, 14 Mar 2011 23:48:39 +0000 (16:48 -0700) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Tue, 15 Mar 2011 00:27:25 +0000 (17:27 -0700) |
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>
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>
upload-pack.c | patch | blob | history |
diff --git a/upload-pack.c b/upload-pack.c
index b40a43f27d0e16f0305153f984741938b3a6ab89..11c3849a79c8be00b709cfd60dfaaa41bc0f1b21 100644 (file)
--- a/upload-pack.c
+++ b/upload-pack.c
static char line[1000];
unsigned char sha1[20];
char last_hex[41];
+ int got_common = 0;
+ int got_other = 0;
save_commit_buffer = 0;
reset_timeout();
if (!len) {
+ if (multi_ack == 2 && got_common
+ && !got_other && ok_to_give_up())
+ packet_write(1, "ACK %s ready\n", last_hex);
if (have_obj.nr == 0 || multi_ack)
packet_write(1, "NAK\n");
if (stateless_rpc)
exit(0);
+ got_common = 0;
+ got_other = 0;
continue;
}
strip(line, len);
if (!prefixcmp(line, "have ")) {
switch (got_sha1(line+5, sha1)) {
case -1: /* they have what we do not */
+ got_other = 1;
if (multi_ack && ok_to_give_up()) {
const char *hex = sha1_to_hex(sha1);
if (multi_ack == 2)
}
break;
default:
+ got_common = 1;
memcpy(last_hex, sha1_to_hex(sha1), 41);
if (multi_ack == 2)
packet_write(1, "ACK %s common\n", last_hex);