summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2014-02-27 22:01:50 (GMT)
committerJunio C Hamano <gitster@pobox.com>2014-02-27 22:01:50 (GMT)
commit2de34784dfcbb4fe0febe9ab98e0b99138040109 (patch)
tree37dfa896cde52f7cfdcf243be8455bdaa0c596c4
parent0f9e62e0847c075678a7a5a748567d1e881d16f8 (diff)
parent0232852b06cb000a3b1f5f48676c8b4d084f18ea (diff)
downloadgit-2de34784dfcbb4fe0febe9ab98e0b99138040109.zip
git-2de34784dfcbb4fe0febe9ab98e0b99138040109.tar.gz
git-2de34784dfcbb4fe0febe9ab98e0b99138040109.tar.bz2
Merge branch 'nd/http-fetch-shallow-fix'
Attempting to deepen a shallow repository by fetching over smart HTTP transport failed in the protocol exchange, when no-done extension was used. The fetching side waited for the list of shallow boundary commits after the sending end stopped talking to it. * nd/http-fetch-shallow-fix: t5537: move http tests out to t5539 fetch-pack: fix deepen shallow over smart http with no-done cap protocol-capabilities.txt: document no-done protocol-capabilities.txt: refer multi_ack_detailed back to pack-protocol.txt pack-protocol.txt: clarify 'obj-id' in the last ACK after 'done' test: rename http fetch and push test files
-rw-r--r--Documentation/technical/pack-protocol.txt3
-rw-r--r--Documentation/technical/protocol-capabilities.txt18
-rw-r--r--fetch-pack.c3
-rwxr-xr-xt/t5537-fetch-shallow.sh27
-rwxr-xr-xt/t5539-fetch-http-shallow.sh82
-rwxr-xr-xt/t5540-http-push-webdav.sh (renamed from t/t5540-http-push.sh)0
-rwxr-xr-xt/t5541-http-push-smart.sh (renamed from t/t5541-http-push.sh)0
-rwxr-xr-xt/t5550-http-fetch-dumb.sh (renamed from t/t5550-http-fetch.sh)0
-rwxr-xr-xt/t5551-http-fetch-smart.sh (renamed from t/t5551-http-fetch.sh)0
9 files changed, 104 insertions, 29 deletions
diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt
index c73b62f..39c6410 100644
--- a/Documentation/technical/pack-protocol.txt
+++ b/Documentation/technical/pack-protocol.txt
@@ -338,7 +338,8 @@ during a prior round. This helps to ensure that at least one common
ancestor is found before we give up entirely.
Once the 'done' line is read from the client, the server will either
-send a final 'ACK obj-id' or it will send a 'NAK'. The server only sends
+send a final 'ACK obj-id' or it will send a 'NAK'. 'obj-id' is the object
+name of the last commit determined to be common. The server only sends
ACK after 'done' if there is at least one common base and multi_ack or
multi_ack_detailed is enabled. The server always sends NAK after 'done'
if there is no common base found.
diff --git a/Documentation/technical/protocol-capabilities.txt b/Documentation/technical/protocol-capabilities.txt
index e3e7924..e174343 100644
--- a/Documentation/technical/protocol-capabilities.txt
+++ b/Documentation/technical/protocol-capabilities.txt
@@ -69,6 +69,24 @@ ends.
Without multi_ack the client would have sent that c-b-a chain anyway,
interleaved with S-R-Q.
+multi_ack_detailed
+------------------
+This is an extension of multi_ack that permits client to better
+understand the server's in-memory state. See pack-protocol.txt,
+section "Packfile Negotiation" for more information.
+
+no-done
+-------
+This capability should only be used with the smart HTTP protocol. If
+multi_ack_detailed and no-done are both present, then the sender is
+free to immediately send a pack following its first "ACK obj-id ready"
+message.
+
+Without no-done in the smart HTTP protocol, the server session would
+end and the client has to make another trip to send "done" before
+the server can send the pack. no-done removes the last round and
+thus slightly reduces latency.
+
thin-pack
---------
diff --git a/fetch-pack.c b/fetch-pack.c
index 90fdd49..f061f1f 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -439,7 +439,8 @@ done:
}
strbuf_release(&req_buf);
- consume_shallow_list(args, fd[0]);
+ if (!got_ready || !no_done)
+ consume_shallow_list(args, fd[0]);
while (flushes || multi_ack) {
int ack = get_ack(fd[0], result_sha1);
if (ack) {
diff --git a/t/t5537-fetch-shallow.sh b/t/t5537-fetch-shallow.sh
index adf215a..3ae9092 100755
--- a/t/t5537-fetch-shallow.sh
+++ b/t/t5537-fetch-shallow.sh
@@ -173,31 +173,4 @@ EOF
)
'
-if test -n "$NO_CURL" -o -z "$GIT_TEST_HTTPD"; then
- say 'skipping remaining tests, git built without http support'
- test_done
-fi
-
-. "$TEST_DIRECTORY"/lib-httpd.sh
-start_httpd
-
-test_expect_success 'clone http repository' '
- git clone --bare --no-local shallow "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
- git clone $HTTPD_URL/smart/repo.git clone &&
- (
- cd clone &&
- git fsck &&
- git log --format=%s origin/master >actual &&
- cat <<EOF >expect &&
-7
-6
-5
-4
-3
-EOF
- test_cmp expect actual
- )
-'
-
-stop_httpd
test_done
diff --git a/t/t5539-fetch-http-shallow.sh b/t/t5539-fetch-http-shallow.sh
new file mode 100755
index 0000000..94553e1
--- /dev/null
+++ b/t/t5539-fetch-http-shallow.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+test_description='fetch/clone from a shallow clone over http'
+
+. ./test-lib.sh
+
+if test -n "$NO_CURL"; then
+ skip_all='skipping test, git built without http support'
+ test_done
+fi
+
+. "$TEST_DIRECTORY"/lib-httpd.sh
+start_httpd
+
+commit() {
+ echo "$1" >tracked &&
+ git add tracked &&
+ git commit -m "$1"
+}
+
+test_expect_success 'setup shallow clone' '
+ commit 1 &&
+ commit 2 &&
+ commit 3 &&
+ commit 4 &&
+ commit 5 &&
+ commit 6 &&
+ commit 7 &&
+ git clone --no-local --depth=5 .git shallow &&
+ git config --global transfer.fsckObjects true
+'
+
+test_expect_success 'clone http repository' '
+ git clone --bare --no-local shallow "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
+ git clone $HTTPD_URL/smart/repo.git clone &&
+ (
+ cd clone &&
+ git fsck &&
+ git log --format=%s origin/master >actual &&
+ cat <<EOF >expect &&
+7
+6
+5
+4
+3
+EOF
+ test_cmp expect actual
+ )
+'
+
+# This test is tricky. We need large enough "have"s that fetch-pack
+# will put pkt-flush in between. Then we need a "have" the server
+# does not have, it'll send "ACK %s ready"
+test_expect_success 'no shallow lines after receiving ACK ready' '
+ (
+ cd shallow &&
+ for i in $(test_seq 15)
+ do
+ git checkout --orphan unrelated$i &&
+ test_commit unrelated$i &&
+ git push -q "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \
+ refs/heads/unrelated$i:refs/heads/unrelated$i &&
+ git push -q ../clone/.git \
+ refs/heads/unrelated$i:refs/heads/unrelated$i ||
+ exit 1
+ done &&
+ git checkout master &&
+ test_commit new &&
+ git push "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" master
+ ) &&
+ (
+ cd clone &&
+ git checkout --orphan newnew &&
+ test_commit new-too &&
+ GIT_TRACE_PACKET="$TRASH_DIRECTORY/trace" git fetch --depth=2 &&
+ grep "fetch-pack< ACK .* ready" ../trace &&
+ ! grep "fetch-pack> done" ../trace
+ )
+'
+
+stop_httpd
+test_done
diff --git a/t/t5540-http-push.sh b/t/t5540-http-push-webdav.sh
index 8d7b3c5..8d7b3c5 100755
--- a/t/t5540-http-push.sh
+++ b/t/t5540-http-push-webdav.sh
diff --git a/t/t5541-http-push.sh b/t/t5541-http-push-smart.sh
index 73af16f..73af16f 100755
--- a/t/t5541-http-push.sh
+++ b/t/t5541-http-push-smart.sh
diff --git a/t/t5550-http-fetch.sh b/t/t5550-http-fetch-dumb.sh
index 1a3a2b6..1a3a2b6 100755
--- a/t/t5550-http-fetch.sh
+++ b/t/t5550-http-fetch-dumb.sh
diff --git a/t/t5551-http-fetch.sh b/t/t5551-http-fetch-smart.sh
index e07eaf3..e07eaf3 100755
--- a/t/t5551-http-fetch.sh
+++ b/t/t5551-http-fetch-smart.sh