2017-10-16 17:55:28 +00:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='test git wire-protocol transition'
|
|
|
|
|
|
|
|
TEST_NO_CREATE_REPO=1
|
|
|
|
|
2019-02-25 21:54:11 +00:00
|
|
|
# This is a protocol-specific test.
|
2019-12-24 01:01:10 +00:00
|
|
|
GIT_TEST_PROTOCOL_VERSION=0
|
|
|
|
export GIT_TEST_PROTOCOL_VERSION
|
2019-02-25 21:54:11 +00:00
|
|
|
|
2020-11-18 23:44:35 +00:00
|
|
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
tests: mark tests relying on the current default for `init.defaultBranch`
In addition to the manual adjustment to let the `linux-gcc` CI job run
the test suite with `master` and then with `main`, this patch makes sure
that GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME is set in all test scripts
that currently rely on the initial branch name being `master by default.
To determine which test scripts to mark up, the first step was to
force-set the default branch name to `master` in
- all test scripts that contain the keyword `master`,
- t4211, which expects `t/t4211/history.export` with a hard-coded ref to
initialize the default branch,
- t5560 because it sources `t/t556x_common` which uses `master`,
- t8002 and t8012 because both source `t/annotate-tests.sh` which also
uses `master`)
This trick was performed by this command:
$ sed -i '/^ *\. \.\/\(test-lib\|lib-\(bash\|cvs\|git-svn\)\|gitweb-lib\)\.sh$/i\
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\
' $(git grep -l master t/t[0-9]*.sh) \
t/t4211*.sh t/t5560*.sh t/t8002*.sh t/t8012*.sh
After that, careful, manual inspection revealed that some of the test
scripts containing the needle `master` do not actually rely on a
specific default branch name: either they mention `master` only in a
comment, or they initialize that branch specificially, or they do not
actually refer to the current default branch. Therefore, the
aforementioned modification was undone in those test scripts thusly:
$ git checkout HEAD -- \
t/t0027-auto-crlf.sh t/t0060-path-utils.sh \
t/t1011-read-tree-sparse-checkout.sh \
t/t1305-config-include.sh t/t1309-early-config.sh \
t/t1402-check-ref-format.sh t/t1450-fsck.sh \
t/t2024-checkout-dwim.sh \
t/t2106-update-index-assume-unchanged.sh \
t/t3040-subprojects-basic.sh t/t3301-notes.sh \
t/t3308-notes-merge.sh t/t3423-rebase-reword.sh \
t/t3436-rebase-more-options.sh \
t/t4015-diff-whitespace.sh t/t4257-am-interactive.sh \
t/t5323-pack-redundant.sh t/t5401-update-hooks.sh \
t/t5511-refspec.sh t/t5526-fetch-submodules.sh \
t/t5529-push-errors.sh t/t5530-upload-pack-error.sh \
t/t5548-push-porcelain.sh \
t/t5552-skipping-fetch-negotiator.sh \
t/t5572-pull-submodule.sh t/t5608-clone-2gb.sh \
t/t5614-clone-submodules-shallow.sh \
t/t7508-status.sh t/t7606-merge-custom.sh \
t/t9302-fast-import-unpack-limit.sh
We excluded one set of test scripts in these commands, though: the range
of `git p4` tests. The reason? `git p4` stores the (foreign) remote
branch in the branch called `p4/master`, which is obviously not the
default branch. Manual analysis revealed that only five of these tests
actually require a specific default branch name to pass; They were
modified thusly:
$ sed -i '/^ *\. \.\/lib-git-p4\.sh$/i\
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\
' t/t980[0167]*.sh t/t9811*.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-18 23:44:19 +00:00
|
|
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|
|
|
|
2017-10-16 17:55:28 +00:00
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
# Test protocol v1 with 'git://' transport
|
|
|
|
#
|
|
|
|
. "$TEST_DIRECTORY"/lib-git-daemon.sh
|
|
|
|
start_git_daemon --export-all --enable=receive-pack
|
|
|
|
daemon_parent=$GIT_DAEMON_DOCUMENT_ROOT_PATH/parent
|
|
|
|
|
|
|
|
test_expect_success 'create repo to be served by git-daemon' '
|
|
|
|
git init "$daemon_parent" &&
|
|
|
|
test_commit -C "$daemon_parent" one
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'clone with git:// using protocol v1' '
|
|
|
|
GIT_TRACE_PACKET=1 git -c protocol.version=1 \
|
|
|
|
clone "$GIT_DAEMON_URL/parent" daemon_child 2>log &&
|
|
|
|
|
|
|
|
git -C daemon_child log -1 --format=%s >actual &&
|
|
|
|
git -C "$daemon_parent" log -1 --format=%s >expect &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Client requested to use protocol v1
|
|
|
|
grep "clone> .*\\\0\\\0version=1\\\0$" log &&
|
|
|
|
# Server responded using protocol v1
|
|
|
|
grep "clone< version 1" log
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'fetch with git:// using protocol v1' '
|
|
|
|
test_commit -C "$daemon_parent" two &&
|
|
|
|
|
|
|
|
GIT_TRACE_PACKET=1 git -C daemon_child -c protocol.version=1 \
|
|
|
|
fetch 2>log &&
|
|
|
|
|
2020-11-18 23:44:35 +00:00
|
|
|
git -C daemon_child log -1 --format=%s origin/main >actual &&
|
2017-10-16 17:55:28 +00:00
|
|
|
git -C "$daemon_parent" log -1 --format=%s >expect &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Client requested to use protocol v1
|
|
|
|
grep "fetch> .*\\\0\\\0version=1\\\0$" log &&
|
|
|
|
# Server responded using protocol v1
|
|
|
|
grep "fetch< version 1" log
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'pull with git:// using protocol v1' '
|
|
|
|
GIT_TRACE_PACKET=1 git -C daemon_child -c protocol.version=1 \
|
|
|
|
pull 2>log &&
|
|
|
|
|
|
|
|
git -C daemon_child log -1 --format=%s >actual &&
|
|
|
|
git -C "$daemon_parent" log -1 --format=%s >expect &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Client requested to use protocol v1
|
|
|
|
grep "fetch> .*\\\0\\\0version=1\\\0$" log &&
|
|
|
|
# Server responded using protocol v1
|
|
|
|
grep "fetch< version 1" log
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push with git:// using protocol v1' '
|
|
|
|
test_commit -C daemon_child three &&
|
|
|
|
|
|
|
|
# Push to another branch, as the target repository has the
|
2020-11-18 23:44:35 +00:00
|
|
|
# main branch checked out and we cannot push into it.
|
2017-10-16 17:55:28 +00:00
|
|
|
GIT_TRACE_PACKET=1 git -C daemon_child -c protocol.version=1 \
|
|
|
|
push origin HEAD:client_branch 2>log &&
|
|
|
|
|
|
|
|
git -C daemon_child log -1 --format=%s >actual &&
|
|
|
|
git -C "$daemon_parent" log -1 --format=%s client_branch >expect &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Client requested to use protocol v1
|
|
|
|
grep "push> .*\\\0\\\0version=1\\\0$" log &&
|
|
|
|
# Server responded using protocol v1
|
|
|
|
grep "push< version 1" log
|
|
|
|
'
|
|
|
|
|
|
|
|
stop_git_daemon
|
|
|
|
|
|
|
|
# Test protocol v1 with 'file://' transport
|
|
|
|
#
|
|
|
|
test_expect_success 'create repo to be served by file:// transport' '
|
|
|
|
git init file_parent &&
|
|
|
|
test_commit -C file_parent one
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'clone with file:// using protocol v1' '
|
|
|
|
GIT_TRACE_PACKET=1 git -c protocol.version=1 \
|
|
|
|
clone "file://$(pwd)/file_parent" file_child 2>log &&
|
|
|
|
|
|
|
|
git -C file_child log -1 --format=%s >actual &&
|
|
|
|
git -C file_parent log -1 --format=%s >expect &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Server responded using protocol v1
|
|
|
|
grep "clone< version 1" log
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'fetch with file:// using protocol v1' '
|
|
|
|
test_commit -C file_parent two &&
|
|
|
|
|
|
|
|
GIT_TRACE_PACKET=1 git -C file_child -c protocol.version=1 \
|
|
|
|
fetch 2>log &&
|
|
|
|
|
2020-11-18 23:44:35 +00:00
|
|
|
git -C file_child log -1 --format=%s origin/main >actual &&
|
2017-10-16 17:55:28 +00:00
|
|
|
git -C file_parent log -1 --format=%s >expect &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Server responded using protocol v1
|
|
|
|
grep "fetch< version 1" log
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'pull with file:// using protocol v1' '
|
|
|
|
GIT_TRACE_PACKET=1 git -C file_child -c protocol.version=1 \
|
|
|
|
pull 2>log &&
|
|
|
|
|
|
|
|
git -C file_child log -1 --format=%s >actual &&
|
|
|
|
git -C file_parent log -1 --format=%s >expect &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Server responded using protocol v1
|
|
|
|
grep "fetch< version 1" log
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push with file:// using protocol v1' '
|
|
|
|
test_commit -C file_child three &&
|
|
|
|
|
|
|
|
# Push to another branch, as the target repository has the
|
2020-11-18 23:44:35 +00:00
|
|
|
# main branch checked out and we cannot push into it.
|
2017-10-16 17:55:28 +00:00
|
|
|
GIT_TRACE_PACKET=1 git -C file_child -c protocol.version=1 \
|
|
|
|
push origin HEAD:client_branch 2>log &&
|
|
|
|
|
|
|
|
git -C file_child log -1 --format=%s >actual &&
|
|
|
|
git -C file_parent log -1 --format=%s client_branch >expect &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Server responded using protocol v1
|
|
|
|
grep "push< version 1" log
|
|
|
|
'
|
|
|
|
|
2022-01-24 18:09:09 +00:00
|
|
|
test_expect_success 'cloning branchless tagless but not refless remote' '
|
|
|
|
rm -rf server client &&
|
|
|
|
|
|
|
|
git -c init.defaultbranch=main init server &&
|
|
|
|
echo foo >server/foo.txt &&
|
|
|
|
git -C server add foo.txt &&
|
|
|
|
git -C server commit -m "message" &&
|
|
|
|
git -C server update-ref refs/notbranch/alsonottag HEAD &&
|
|
|
|
git -C server checkout --detach &&
|
|
|
|
git -C server branch -D main &&
|
|
|
|
git -C server symbolic-ref HEAD refs/heads/nonexistentbranch &&
|
|
|
|
|
|
|
|
git -c protocol.version=1 clone "file://$(pwd)/server" client
|
|
|
|
'
|
|
|
|
|
2017-10-16 17:55:28 +00:00
|
|
|
# Test protocol v1 with 'ssh://' transport
|
|
|
|
#
|
|
|
|
test_expect_success 'setup ssh wrapper' '
|
|
|
|
GIT_SSH="$GIT_BUILD_DIR/t/helper/test-fake-ssh" &&
|
|
|
|
export GIT_SSH &&
|
2017-10-16 17:55:31 +00:00
|
|
|
GIT_SSH_VARIANT=ssh &&
|
|
|
|
export GIT_SSH_VARIANT &&
|
2017-10-16 17:55:28 +00:00
|
|
|
export TRASH_DIRECTORY &&
|
|
|
|
>"$TRASH_DIRECTORY"/ssh-output
|
|
|
|
'
|
|
|
|
|
|
|
|
expect_ssh () {
|
|
|
|
test_when_finished '(cd "$TRASH_DIRECTORY" && rm -f ssh-expect && >ssh-output)' &&
|
|
|
|
echo "ssh: -o SendEnv=GIT_PROTOCOL myhost $1 '$PWD/ssh_parent'" >"$TRASH_DIRECTORY/ssh-expect" &&
|
|
|
|
(cd "$TRASH_DIRECTORY" && test_cmp ssh-expect ssh-output)
|
|
|
|
}
|
|
|
|
|
|
|
|
test_expect_success 'create repo to be served by ssh:// transport' '
|
|
|
|
git init ssh_parent &&
|
|
|
|
test_commit -C ssh_parent one
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'clone with ssh:// using protocol v1' '
|
|
|
|
GIT_TRACE_PACKET=1 git -c protocol.version=1 \
|
|
|
|
clone "ssh://myhost:$(pwd)/ssh_parent" ssh_child 2>log &&
|
|
|
|
expect_ssh git-upload-pack &&
|
|
|
|
|
|
|
|
git -C ssh_child log -1 --format=%s >actual &&
|
|
|
|
git -C ssh_parent log -1 --format=%s >expect &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Server responded using protocol v1
|
|
|
|
grep "clone< version 1" log
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'fetch with ssh:// using protocol v1' '
|
|
|
|
test_commit -C ssh_parent two &&
|
|
|
|
|
|
|
|
GIT_TRACE_PACKET=1 git -C ssh_child -c protocol.version=1 \
|
|
|
|
fetch 2>log &&
|
|
|
|
expect_ssh git-upload-pack &&
|
|
|
|
|
2020-11-18 23:44:35 +00:00
|
|
|
git -C ssh_child log -1 --format=%s origin/main >actual &&
|
2017-10-16 17:55:28 +00:00
|
|
|
git -C ssh_parent log -1 --format=%s >expect &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Server responded using protocol v1
|
|
|
|
grep "fetch< version 1" log
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'pull with ssh:// using protocol v1' '
|
|
|
|
GIT_TRACE_PACKET=1 git -C ssh_child -c protocol.version=1 \
|
|
|
|
pull 2>log &&
|
|
|
|
expect_ssh git-upload-pack &&
|
|
|
|
|
|
|
|
git -C ssh_child log -1 --format=%s >actual &&
|
|
|
|
git -C ssh_parent log -1 --format=%s >expect &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Server responded using protocol v1
|
|
|
|
grep "fetch< version 1" log
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push with ssh:// using protocol v1' '
|
|
|
|
test_commit -C ssh_child three &&
|
|
|
|
|
|
|
|
# Push to another branch, as the target repository has the
|
2020-11-18 23:44:35 +00:00
|
|
|
# main branch checked out and we cannot push into it.
|
2017-10-16 17:55:28 +00:00
|
|
|
GIT_TRACE_PACKET=1 git -C ssh_child -c protocol.version=1 \
|
|
|
|
push origin HEAD:client_branch 2>log &&
|
|
|
|
expect_ssh git-receive-pack &&
|
|
|
|
|
|
|
|
git -C ssh_child log -1 --format=%s >actual &&
|
|
|
|
git -C ssh_parent log -1 --format=%s client_branch >expect &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Server responded using protocol v1
|
|
|
|
grep "push< version 1" log
|
|
|
|
'
|
|
|
|
|
upload-pack: advertise capabilities when cloning empty repos
When cloning an empty repository, protocol versions 0 and 1 currently
offer nothing but the header and flush packets for the /info/refs
endpoint. This means that no capabilities are provided, so the client
side doesn't know what capabilities are present.
However, this does pose a problem when working with SHA-256
repositories, since we use the capabilities to know the remote side's
object format (hash algorithm). As of 8b214c2e9d ("clone: propagate
object-format when cloning from void", 2023-04-05), this has been fixed
for protocol v2, since there we always read the hash algorithm from the
remote.
Fortunately, the push version of the protocol already indicates a clue
for how to solve this. When the /info/refs endpoint is accessed for a
push and the remote is empty, we include a dummy "capabilities^{}" ref
pointing to the all-zeros object ID. The protocol documentation already
indicates this should _always_ be sent, even for fetches and clones, so
let's just do that, which means we'll properly announce the hash
algorithm as part of the capabilities. This just works with the
existing code because we share the same ref code for fetches and clones,
and libgit2, JGit, and dulwich do as well.
There is one minor issue to fix, though. If we called send_ref with
namespaces, we would return NULL with the capabilities entry, which
would cause a crash. Instead, let's refactor out a function to print
just the ref itself without stripping the namespace and use it for our
special capabilities entry.
Add several sets of tests for HTTP as well as for local clones. The
behavior can be slightly different for HTTP versus a local or SSH clone
because of the stateless-rpc functionality, so it's worth testing both.
Signed-off-by: brian m. carlson <bk2204@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-05-17 19:24:43 +00:00
|
|
|
test_expect_success 'clone propagates object-format from empty repo' '
|
|
|
|
test_when_finished "rm -fr src256 dst256" &&
|
|
|
|
|
|
|
|
echo sha256 >expect &&
|
|
|
|
git init --object-format=sha256 src256 &&
|
|
|
|
git clone --no-local src256 dst256 &&
|
|
|
|
git -C dst256 rev-parse --show-object-format >actual &&
|
|
|
|
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2017-10-16 17:55:29 +00:00
|
|
|
# Test protocol v1 with 'http://' transport
|
|
|
|
#
|
|
|
|
. "$TEST_DIRECTORY"/lib-httpd.sh
|
|
|
|
start_httpd
|
|
|
|
|
upload-pack: advertise capabilities when cloning empty repos
When cloning an empty repository, protocol versions 0 and 1 currently
offer nothing but the header and flush packets for the /info/refs
endpoint. This means that no capabilities are provided, so the client
side doesn't know what capabilities are present.
However, this does pose a problem when working with SHA-256
repositories, since we use the capabilities to know the remote side's
object format (hash algorithm). As of 8b214c2e9d ("clone: propagate
object-format when cloning from void", 2023-04-05), this has been fixed
for protocol v2, since there we always read the hash algorithm from the
remote.
Fortunately, the push version of the protocol already indicates a clue
for how to solve this. When the /info/refs endpoint is accessed for a
push and the remote is empty, we include a dummy "capabilities^{}" ref
pointing to the all-zeros object ID. The protocol documentation already
indicates this should _always_ be sent, even for fetches and clones, so
let's just do that, which means we'll properly announce the hash
algorithm as part of the capabilities. This just works with the
existing code because we share the same ref code for fetches and clones,
and libgit2, JGit, and dulwich do as well.
There is one minor issue to fix, though. If we called send_ref with
namespaces, we would return NULL with the capabilities entry, which
would cause a crash. Instead, let's refactor out a function to print
just the ref itself without stripping the namespace and use it for our
special capabilities entry.
Add several sets of tests for HTTP as well as for local clones. The
behavior can be slightly different for HTTP versus a local or SSH clone
because of the stateless-rpc functionality, so it's worth testing both.
Signed-off-by: brian m. carlson <bk2204@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-05-17 19:24:43 +00:00
|
|
|
test_expect_success 'create repos to be served by http:// transport' '
|
2017-10-16 17:55:29 +00:00
|
|
|
git init "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" &&
|
|
|
|
git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" config http.receivepack true &&
|
upload-pack: advertise capabilities when cloning empty repos
When cloning an empty repository, protocol versions 0 and 1 currently
offer nothing but the header and flush packets for the /info/refs
endpoint. This means that no capabilities are provided, so the client
side doesn't know what capabilities are present.
However, this does pose a problem when working with SHA-256
repositories, since we use the capabilities to know the remote side's
object format (hash algorithm). As of 8b214c2e9d ("clone: propagate
object-format when cloning from void", 2023-04-05), this has been fixed
for protocol v2, since there we always read the hash algorithm from the
remote.
Fortunately, the push version of the protocol already indicates a clue
for how to solve this. When the /info/refs endpoint is accessed for a
push and the remote is empty, we include a dummy "capabilities^{}" ref
pointing to the all-zeros object ID. The protocol documentation already
indicates this should _always_ be sent, even for fetches and clones, so
let's just do that, which means we'll properly announce the hash
algorithm as part of the capabilities. This just works with the
existing code because we share the same ref code for fetches and clones,
and libgit2, JGit, and dulwich do as well.
There is one minor issue to fix, though. If we called send_ref with
namespaces, we would return NULL with the capabilities entry, which
would cause a crash. Instead, let's refactor out a function to print
just the ref itself without stripping the namespace and use it for our
special capabilities entry.
Add several sets of tests for HTTP as well as for local clones. The
behavior can be slightly different for HTTP versus a local or SSH clone
because of the stateless-rpc functionality, so it's worth testing both.
Signed-off-by: brian m. carlson <bk2204@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-05-17 19:24:43 +00:00
|
|
|
test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" one &&
|
|
|
|
git init --object-format=sha256 "$HTTPD_DOCUMENT_ROOT_PATH/sha256" &&
|
|
|
|
git -C "$HTTPD_DOCUMENT_ROOT_PATH/sha256" config http.receivepack true
|
2017-10-16 17:55:29 +00:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'clone with http:// using protocol v1' '
|
|
|
|
GIT_TRACE_PACKET=1 GIT_TRACE_CURL=1 git -c protocol.version=1 \
|
|
|
|
clone "$HTTPD_URL/smart/http_parent" http_child 2>log &&
|
|
|
|
|
|
|
|
git -C http_child log -1 --format=%s >actual &&
|
|
|
|
git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s >expect &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Client requested to use protocol v1
|
|
|
|
grep "Git-Protocol: version=1" log &&
|
|
|
|
# Server responded using protocol v1
|
|
|
|
grep "git< version 1" log
|
|
|
|
'
|
|
|
|
|
upload-pack: advertise capabilities when cloning empty repos
When cloning an empty repository, protocol versions 0 and 1 currently
offer nothing but the header and flush packets for the /info/refs
endpoint. This means that no capabilities are provided, so the client
side doesn't know what capabilities are present.
However, this does pose a problem when working with SHA-256
repositories, since we use the capabilities to know the remote side's
object format (hash algorithm). As of 8b214c2e9d ("clone: propagate
object-format when cloning from void", 2023-04-05), this has been fixed
for protocol v2, since there we always read the hash algorithm from the
remote.
Fortunately, the push version of the protocol already indicates a clue
for how to solve this. When the /info/refs endpoint is accessed for a
push and the remote is empty, we include a dummy "capabilities^{}" ref
pointing to the all-zeros object ID. The protocol documentation already
indicates this should _always_ be sent, even for fetches and clones, so
let's just do that, which means we'll properly announce the hash
algorithm as part of the capabilities. This just works with the
existing code because we share the same ref code for fetches and clones,
and libgit2, JGit, and dulwich do as well.
There is one minor issue to fix, though. If we called send_ref with
namespaces, we would return NULL with the capabilities entry, which
would cause a crash. Instead, let's refactor out a function to print
just the ref itself without stripping the namespace and use it for our
special capabilities entry.
Add several sets of tests for HTTP as well as for local clones. The
behavior can be slightly different for HTTP versus a local or SSH clone
because of the stateless-rpc functionality, so it's worth testing both.
Signed-off-by: brian m. carlson <bk2204@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-05-17 19:24:43 +00:00
|
|
|
test_expect_success 'clone with http:// using protocol v1 with empty SHA-256 repo' '
|
|
|
|
GIT_TRACE_PACKET=1 GIT_TRACE_CURL=1 git -c protocol.version=1 \
|
|
|
|
clone "$HTTPD_URL/smart/sha256" sha256 2>log &&
|
|
|
|
|
|
|
|
echo sha256 >expect &&
|
|
|
|
git -C sha256 rev-parse --show-object-format >actual &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Client requested to use protocol v1
|
|
|
|
grep "Git-Protocol: version=1" log &&
|
|
|
|
# Server responded using protocol v1
|
|
|
|
grep "git< version 1" log
|
|
|
|
'
|
|
|
|
|
2017-10-16 17:55:29 +00:00
|
|
|
test_expect_success 'fetch with http:// using protocol v1' '
|
|
|
|
test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" two &&
|
|
|
|
|
|
|
|
GIT_TRACE_PACKET=1 git -C http_child -c protocol.version=1 \
|
|
|
|
fetch 2>log &&
|
|
|
|
|
2020-11-18 23:44:35 +00:00
|
|
|
git -C http_child log -1 --format=%s origin/main >actual &&
|
2017-10-16 17:55:29 +00:00
|
|
|
git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s >expect &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Server responded using protocol v1
|
|
|
|
grep "git< version 1" log
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'pull with http:// using protocol v1' '
|
|
|
|
GIT_TRACE_PACKET=1 git -C http_child -c protocol.version=1 \
|
|
|
|
pull 2>log &&
|
|
|
|
|
|
|
|
git -C http_child log -1 --format=%s >actual &&
|
|
|
|
git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s >expect &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Server responded using protocol v1
|
|
|
|
grep "git< version 1" log
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push with http:// using protocol v1' '
|
|
|
|
test_commit -C http_child three &&
|
|
|
|
|
|
|
|
# Push to another branch, as the target repository has the
|
2020-11-18 23:44:35 +00:00
|
|
|
# main branch checked out and we cannot push into it.
|
2017-10-16 17:55:29 +00:00
|
|
|
GIT_TRACE_PACKET=1 git -C http_child -c protocol.version=1 \
|
|
|
|
push origin HEAD:client_branch && #2>log &&
|
|
|
|
|
|
|
|
git -C http_child log -1 --format=%s >actual &&
|
|
|
|
git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s client_branch >expect &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Server responded using protocol v1
|
|
|
|
grep "git< version 1" log
|
|
|
|
'
|
|
|
|
|
2019-08-01 15:53:09 +00:00
|
|
|
# DO NOT add non-httpd-specific tests here, because the last part of this
|
|
|
|
# test script is only executed when httpd is available and enabled.
|
|
|
|
|
2017-10-16 17:55:28 +00:00
|
|
|
test_done
|