9c1e657a8f
Currently, the packfile negotiation step within a Git fetch cannot be done independent of sending the packfile, even though there is at least one application wherein this is useful. Therefore, make it possible for this negotiation step to be done independently. A subsequent commit will use this for one such application - push negotiation. This feature is for protocol v2 only. (An implementation for protocol v0 would require a separate implementation in the fetch, transport, and transport helper code.) In the protocol, the main hindrance towards independent negotiation is that the server can unilaterally decide to send the packfile. This is solved by a "wait-for-done" argument: the server will then wait for the client to say "done". In practice, the client will never say it; instead it will cease requests once it is satisfied. In the client, the main change lies in the transport and transport helper code. fetch_refs_via_pack() performs everything needed - protocol version and capability checks, and the negotiation itself. There are 2 code paths that do not go through fetch_refs_via_pack() that needed to be individually excluded: the bundle transport (excluded through requiring smart_options, which the bundle transport doesn't support) and transport helpers that do not support takeover. If or when we support independent negotiation for protocol v0, we will need to modify these 2 code paths to support it. But for now, report failure if independent negotiation is requested in these cases. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
244 lines
5.4 KiB
Bash
Executable File
244 lines
5.4 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
test_description='test protocol v2 server commands'
|
|
|
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|
|
|
. ./test-lib.sh
|
|
|
|
test_expect_success 'test capability advertisement' '
|
|
test_oid_cache <<-EOF &&
|
|
wrong_algo sha1:sha256
|
|
wrong_algo sha256:sha1
|
|
EOF
|
|
cat >expect <<-EOF &&
|
|
version 2
|
|
agent=git/$(git version | cut -d" " -f3)
|
|
ls-refs=unborn
|
|
fetch=shallow wait-for-done
|
|
server-option
|
|
object-format=$(test_oid algo)
|
|
0000
|
|
EOF
|
|
|
|
GIT_TEST_SIDEBAND_ALL=0 test-tool serve-v2 \
|
|
--advertise-capabilities >out &&
|
|
test-tool pkt-line unpack <out >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'stateless-rpc flag does not list capabilities' '
|
|
# Empty request
|
|
test-tool pkt-line pack >in <<-EOF &&
|
|
0000
|
|
EOF
|
|
test-tool serve-v2 --stateless-rpc >out <in &&
|
|
test_must_be_empty out &&
|
|
|
|
# EOF
|
|
test-tool serve-v2 --stateless-rpc >out &&
|
|
test_must_be_empty out
|
|
'
|
|
|
|
test_expect_success 'request invalid capability' '
|
|
test-tool pkt-line pack >in <<-EOF &&
|
|
foobar
|
|
0000
|
|
EOF
|
|
test_must_fail test-tool serve-v2 --stateless-rpc 2>err <in &&
|
|
test_i18ngrep "unknown capability" err
|
|
'
|
|
|
|
test_expect_success 'request with no command' '
|
|
test-tool pkt-line pack >in <<-EOF &&
|
|
agent=git/test
|
|
object-format=$(test_oid algo)
|
|
0000
|
|
EOF
|
|
test_must_fail test-tool serve-v2 --stateless-rpc 2>err <in &&
|
|
test_i18ngrep "no command requested" err
|
|
'
|
|
|
|
test_expect_success 'request invalid command' '
|
|
test-tool pkt-line pack >in <<-EOF &&
|
|
command=foo
|
|
object-format=$(test_oid algo)
|
|
agent=git/test
|
|
0000
|
|
EOF
|
|
test_must_fail test-tool serve-v2 --stateless-rpc 2>err <in &&
|
|
test_i18ngrep "invalid command" err
|
|
'
|
|
|
|
test_expect_success 'wrong object-format' '
|
|
test-tool pkt-line pack >in <<-EOF &&
|
|
command=fetch
|
|
agent=git/test
|
|
object-format=$(test_oid wrong_algo)
|
|
0000
|
|
EOF
|
|
test_must_fail test-tool serve-v2 --stateless-rpc 2>err <in &&
|
|
test_i18ngrep "mismatched object format" err
|
|
'
|
|
|
|
# Test the basics of ls-refs
|
|
#
|
|
test_expect_success 'setup some refs and tags' '
|
|
test_commit one &&
|
|
git branch dev main &&
|
|
test_commit two &&
|
|
git symbolic-ref refs/heads/release refs/heads/main &&
|
|
git tag -a -m "annotated tag" annotated-tag
|
|
'
|
|
|
|
test_expect_success 'basics of ls-refs' '
|
|
test-tool pkt-line pack >in <<-EOF &&
|
|
command=ls-refs
|
|
object-format=$(test_oid algo)
|
|
0000
|
|
EOF
|
|
|
|
cat >expect <<-EOF &&
|
|
$(git rev-parse HEAD) HEAD
|
|
$(git rev-parse refs/heads/dev) refs/heads/dev
|
|
$(git rev-parse refs/heads/main) refs/heads/main
|
|
$(git rev-parse refs/heads/release) refs/heads/release
|
|
$(git rev-parse refs/tags/annotated-tag) refs/tags/annotated-tag
|
|
$(git rev-parse refs/tags/one) refs/tags/one
|
|
$(git rev-parse refs/tags/two) refs/tags/two
|
|
0000
|
|
EOF
|
|
|
|
test-tool serve-v2 --stateless-rpc <in >out &&
|
|
test-tool pkt-line unpack <out >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'basic ref-prefixes' '
|
|
test-tool pkt-line pack >in <<-EOF &&
|
|
command=ls-refs
|
|
object-format=$(test_oid algo)
|
|
0001
|
|
ref-prefix refs/heads/main
|
|
ref-prefix refs/tags/one
|
|
0000
|
|
EOF
|
|
|
|
cat >expect <<-EOF &&
|
|
$(git rev-parse refs/heads/main) refs/heads/main
|
|
$(git rev-parse refs/tags/one) refs/tags/one
|
|
0000
|
|
EOF
|
|
|
|
test-tool serve-v2 --stateless-rpc <in >out &&
|
|
test-tool pkt-line unpack <out >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'refs/heads prefix' '
|
|
test-tool pkt-line pack >in <<-EOF &&
|
|
command=ls-refs
|
|
object-format=$(test_oid algo)
|
|
0001
|
|
ref-prefix refs/heads/
|
|
0000
|
|
EOF
|
|
|
|
cat >expect <<-EOF &&
|
|
$(git rev-parse refs/heads/dev) refs/heads/dev
|
|
$(git rev-parse refs/heads/main) refs/heads/main
|
|
$(git rev-parse refs/heads/release) refs/heads/release
|
|
0000
|
|
EOF
|
|
|
|
test-tool serve-v2 --stateless-rpc <in >out &&
|
|
test-tool pkt-line unpack <out >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'peel parameter' '
|
|
test-tool pkt-line pack >in <<-EOF &&
|
|
command=ls-refs
|
|
object-format=$(test_oid algo)
|
|
0001
|
|
peel
|
|
ref-prefix refs/tags/
|
|
0000
|
|
EOF
|
|
|
|
cat >expect <<-EOF &&
|
|
$(git rev-parse refs/tags/annotated-tag) refs/tags/annotated-tag peeled:$(git rev-parse refs/tags/annotated-tag^{})
|
|
$(git rev-parse refs/tags/one) refs/tags/one
|
|
$(git rev-parse refs/tags/two) refs/tags/two
|
|
0000
|
|
EOF
|
|
|
|
test-tool serve-v2 --stateless-rpc <in >out &&
|
|
test-tool pkt-line unpack <out >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'symrefs parameter' '
|
|
test-tool pkt-line pack >in <<-EOF &&
|
|
command=ls-refs
|
|
object-format=$(test_oid algo)
|
|
0001
|
|
symrefs
|
|
ref-prefix refs/heads/
|
|
0000
|
|
EOF
|
|
|
|
cat >expect <<-EOF &&
|
|
$(git rev-parse refs/heads/dev) refs/heads/dev
|
|
$(git rev-parse refs/heads/main) refs/heads/main
|
|
$(git rev-parse refs/heads/release) refs/heads/release symref-target:refs/heads/main
|
|
0000
|
|
EOF
|
|
|
|
test-tool serve-v2 --stateless-rpc <in >out &&
|
|
test-tool pkt-line unpack <out >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'sending server-options' '
|
|
test-tool pkt-line pack >in <<-EOF &&
|
|
command=ls-refs
|
|
object-format=$(test_oid algo)
|
|
server-option=hello
|
|
server-option=world
|
|
0001
|
|
ref-prefix HEAD
|
|
0000
|
|
EOF
|
|
|
|
cat >expect <<-EOF &&
|
|
$(git rev-parse HEAD) HEAD
|
|
0000
|
|
EOF
|
|
|
|
test-tool serve-v2 --stateless-rpc <in >out &&
|
|
test-tool pkt-line unpack <out >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'unexpected lines are not allowed in fetch request' '
|
|
git init server &&
|
|
|
|
test-tool pkt-line pack >in <<-EOF &&
|
|
command=fetch
|
|
object-format=$(test_oid algo)
|
|
0001
|
|
this-is-not-a-command
|
|
0000
|
|
EOF
|
|
|
|
(
|
|
cd server &&
|
|
test_must_fail test-tool serve-v2 --stateless-rpc
|
|
) <in >/dev/null 2>err &&
|
|
grep "unexpected line: .this-is-not-a-command." err
|
|
'
|
|
|
|
test_done
|