git/t/t5512-ls-remote.sh

344 строки
9.9 KiB
Bash
Исходник Обычный вид История

#!/bin/sh
test_description='git ls-remote'
. ./test-lib.sh
test_expect_success setup '
>file &&
git add file &&
test_tick &&
git commit -m initial &&
git tag mark &&
git tag mark1.1 &&
git tag mark1.2 &&
git tag mark1.10 &&
git show-ref --tags -d | sed -e "s/ / /" >expected.tag &&
(
echo "$(git rev-parse HEAD) HEAD" &&
git show-ref -d | sed -e "s/ / /"
) >expected.all &&
git remote add self "$(pwd)/.git"
'
test_expect_success 'ls-remote --tags .git' '
git ls-remote --tags .git >actual &&
test_cmp expected.tag actual
'
test_expect_success 'ls-remote .git' '
git ls-remote .git >actual &&
test_cmp expected.all actual
'
test_expect_success 'ls-remote --tags self' '
git ls-remote --tags self >actual &&
test_cmp expected.tag actual
'
test_expect_success 'ls-remote self' '
git ls-remote self >actual &&
test_cmp expected.all actual
'
test_expect_success 'ls-remote --sort="version:refname" --tags self' '
cat >expect <<-EOF &&
$(git rev-parse mark) refs/tags/mark
$(git rev-parse mark1.1) refs/tags/mark1.1
$(git rev-parse mark1.2) refs/tags/mark1.2
$(git rev-parse mark1.10) refs/tags/mark1.10
EOF
git ls-remote --sort="version:refname" --tags self >actual &&
test_cmp expect actual
'
test_expect_success 'ls-remote --sort="-version:refname" --tags self' '
cat >expect <<-EOF &&
$(git rev-parse mark1.10) refs/tags/mark1.10
$(git rev-parse mark1.2) refs/tags/mark1.2
$(git rev-parse mark1.1) refs/tags/mark1.1
$(git rev-parse mark) refs/tags/mark
EOF
git ls-remote --sort="-version:refname" --tags self >actual &&
test_cmp expect actual
'
test_expect_success 'ls-remote --sort="-refname" --tags self' '
cat >expect <<-EOF &&
$(git rev-parse mark1.2) refs/tags/mark1.2
$(git rev-parse mark1.10) refs/tags/mark1.10
$(git rev-parse mark1.1) refs/tags/mark1.1
$(git rev-parse mark) refs/tags/mark
EOF
git ls-remote --sort="-refname" --tags self >actual &&
test_cmp expect actual
'
test_expect_success 'dies when no remote specified and no default remotes found' '
test_must_fail git ls-remote
'
test_expect_success 'use "origin" when no remote specified' '
URL="$(pwd)/.git" &&
echo "From $URL" >exp_err &&
git remote add origin "$URL" &&
git ls-remote 2>actual_err >actual &&
test_cmp exp_err actual_err &&
test_cmp expected.all actual
'
test_expect_success 'suppress "From <url>" with -q' '
git ls-remote -q 2>actual_err &&
! test_cmp exp_err actual_err
'
test_expect_success 'use branch.<name>.remote if possible' '
#
# Test that we are indeed using branch.<name>.remote, not "origin", even
# though the "origin" remote has been set.
#
# setup a new remote to differentiate from "origin"
git clone . other.git &&
(
cd other.git &&
echo "$(git rev-parse HEAD) HEAD" &&
git show-ref | sed -e "s/ / /"
) >exp &&
URL="other.git" &&
echo "From $URL" >exp_err &&
git remote add other $URL &&
git config branch.master.remote other &&
git ls-remote 2>actual_err >actual &&
test_cmp exp_err actual_err &&
test_cmp exp actual
'
test_expect_success 'confuses pattern as remote when no remote specified' '
if test_have_prereq MINGW
then
# Windows does not like asterisks in pathname
does_not_exist=master
else
does_not_exist="refs*master"
fi &&
cat >exp <<-EOF &&
fatal: '\''$does_not_exist'\'' does not appear to be a git repository
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
EOF
#
# Do not expect "git ls-remote <pattern>" to work; ls-remote needs
# <remote> if you want to feed <pattern>, just like you cannot say
# fetch <branch>.
# We could just as easily have used "master"; the "*" emphasizes its
# role as a pattern.
test_must_fail git ls-remote "$does_not_exist" >actual 2>&1 &&
test_i18ncmp exp actual
'
test_expect_success 'die with non-2 for wrong repository even with --exit-code' '
{
git ls-remote --exit-code ./no-such-repository
status=$?
} &&
test $status != 2 && test $status != 0
'
test_expect_success 'Report success even when nothing matches' '
git ls-remote other.git "refs/nsn/*" >actual &&
test_must_be_empty actual
'
test_expect_success 'Report no-match with --exit-code' '
test_expect_code 2 git ls-remote --exit-code other.git "refs/nsn/*" >actual &&
test_must_be_empty actual
'
test_expect_success 'Report match with --exit-code' '
git ls-remote --exit-code other.git "refs/tags/*" >actual &&
git ls-remote . tags/mark* >expect &&
test_cmp expect actual
'
refs: support negative transfer.hideRefs If you hide a hierarchy of refs using the transfer.hideRefs config, there is no way to later override that config to "unhide" it. This patch implements a "negative" hide which causes matches to immediately be marked as unhidden, even if another match would hide it. We take care to apply the matches in reverse-order from how they are fed to us by the config machinery, as that lets our usual "last one wins" config precedence work (and entries in .git/config, for example, will override /etc/gitconfig). So you can now do: $ git config --system transfer.hideRefs refs/secret $ git config transfer.hideRefs '!refs/secret/not-so-secret' to hide refs/secret in all repos, except for one public bit in one specific repo. Or you can even do: $ git clone \ -u "git -c transfer.hiderefs="!refs/foo" upload-pack" \ remote:repo.git to clone remote:repo.git, overriding any hiding it has configured. There are two alternatives that were considered and rejected: 1. A generic config mechanism for removing an item from a list. E.g.: (e.g., "[transfer] hideRefs -= refs/foo"). This is nice because it could apply to other multi-valued config, as well. But it is not nearly as flexible. There is no way to say: [transfer] hideRefs = refs/secret hideRefs = refs/secret/not-so-secret Having explicit negative specifications means we can override previous entries, even if they are not the same literal string. 2. Adding another variable to override some parts of hideRefs (e.g., "exposeRefs"). This solves the problem from alternative (1), but it cannot easily obey the normal config precedence, because it would use two separate lists. For example: [transfer] hideRefs = refs/secret exposeRefs = refs/secret/not-so-secret hideRefs = refs/secret/not-so-secret/no-really-its-secret With two lists, we have to apply the "expose" rules first, and only then apply the "hide" rules. But that does not match what the above config intends. Of course we could internally parse that to a single list, respecting the ordering, which saves us having to invent the new "!" syntax. But using a single name communicates to the user that the ordering _is_ important. And "!" is well-known for negation, and should not appear at the beginning of a ref (it is actually valid in a ref-name, but all entries here should be fully-qualified, starting with "refs/"). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-07-28 23:23:26 +03:00
test_expect_success 'set up some extra tags for ref hiding' '
git tag magic/one &&
git tag magic/two
'
upload/receive-pack: allow hiding ref hierarchies A repository may have refs that are only used for its internal bookkeeping purposes that should not be exposed to the others that come over the network. Teach upload-pack to omit some refs from its initial advertisement by paying attention to the uploadpack.hiderefs multi-valued configuration variable. Do the same to receive-pack via the receive.hiderefs variable. As a convenient short-hand, allow using transfer.hiderefs to set the value to both of these variables. Any ref that is under the hierarchies listed on the value of these variable is excluded from responses to requests made by "ls-remote", "fetch", etc. (for upload-pack) and "push" (for receive-pack). Because these hidden refs do not count as OUR_REF, an attempt to fetch objects at the tip of them will be rejected, and because these refs do not get advertised, "git push :" will not see local branches that have the same name as them as "matching" ones to be sent. An attempt to update/delete these hidden refs with an explicit refspec, e.g. "git push origin :refs/hidden/22", is rejected. This is not a new restriction. To the pusher, it would appear that there is no such ref, so its push request will conclude with "Now that I sent you all the data, it is time for you to update the refs. I saw that the ref did not exist when I started pushing, and I want the result to point at this commit". The receiving end will apply the compare-and-swap rule to this request and rejects the push with "Well, your update request conflicts with somebody else; I see there is such a ref.", which is the right thing to do. Otherwise a push to a hidden ref will always be "the last one wins", which is not a good default. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-01-19 04:08:30 +04:00
for configsection in transfer uploadpack
do
test_expect_success "Hide some refs with $configsection.hiderefs" '
test_config $configsection.hiderefs refs/tags &&
git ls-remote . >actual &&
test_unconfig $configsection.hiderefs &&
git ls-remote . |
sed -e "/ refs\/tags\//d" >expect &&
test_cmp expect actual
'
refs: support negative transfer.hideRefs If you hide a hierarchy of refs using the transfer.hideRefs config, there is no way to later override that config to "unhide" it. This patch implements a "negative" hide which causes matches to immediately be marked as unhidden, even if another match would hide it. We take care to apply the matches in reverse-order from how they are fed to us by the config machinery, as that lets our usual "last one wins" config precedence work (and entries in .git/config, for example, will override /etc/gitconfig). So you can now do: $ git config --system transfer.hideRefs refs/secret $ git config transfer.hideRefs '!refs/secret/not-so-secret' to hide refs/secret in all repos, except for one public bit in one specific repo. Or you can even do: $ git clone \ -u "git -c transfer.hiderefs="!refs/foo" upload-pack" \ remote:repo.git to clone remote:repo.git, overriding any hiding it has configured. There are two alternatives that were considered and rejected: 1. A generic config mechanism for removing an item from a list. E.g.: (e.g., "[transfer] hideRefs -= refs/foo"). This is nice because it could apply to other multi-valued config, as well. But it is not nearly as flexible. There is no way to say: [transfer] hideRefs = refs/secret hideRefs = refs/secret/not-so-secret Having explicit negative specifications means we can override previous entries, even if they are not the same literal string. 2. Adding another variable to override some parts of hideRefs (e.g., "exposeRefs"). This solves the problem from alternative (1), but it cannot easily obey the normal config precedence, because it would use two separate lists. For example: [transfer] hideRefs = refs/secret exposeRefs = refs/secret/not-so-secret hideRefs = refs/secret/not-so-secret/no-really-its-secret With two lists, we have to apply the "expose" rules first, and only then apply the "hide" rules. But that does not match what the above config intends. Of course we could internally parse that to a single list, respecting the ordering, which saves us having to invent the new "!" syntax. But using a single name communicates to the user that the ordering _is_ important. And "!" is well-known for negation, and should not appear at the beginning of a ref (it is actually valid in a ref-name, but all entries here should be fully-qualified, starting with "refs/"). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-07-28 23:23:26 +03:00
test_expect_success "Override hiding of $configsection.hiderefs" '
test_when_finished "test_unconfig $configsection.hiderefs" &&
git config --add $configsection.hiderefs refs/tags &&
git config --add $configsection.hiderefs "!refs/tags/magic" &&
git config --add $configsection.hiderefs refs/tags/magic/one &&
git ls-remote . >actual &&
grep refs/tags/magic/two actual &&
! grep refs/tags/magic/one actual
'
upload/receive-pack: allow hiding ref hierarchies A repository may have refs that are only used for its internal bookkeeping purposes that should not be exposed to the others that come over the network. Teach upload-pack to omit some refs from its initial advertisement by paying attention to the uploadpack.hiderefs multi-valued configuration variable. Do the same to receive-pack via the receive.hiderefs variable. As a convenient short-hand, allow using transfer.hiderefs to set the value to both of these variables. Any ref that is under the hierarchies listed on the value of these variable is excluded from responses to requests made by "ls-remote", "fetch", etc. (for upload-pack) and "push" (for receive-pack). Because these hidden refs do not count as OUR_REF, an attempt to fetch objects at the tip of them will be rejected, and because these refs do not get advertised, "git push :" will not see local branches that have the same name as them as "matching" ones to be sent. An attempt to update/delete these hidden refs with an explicit refspec, e.g. "git push origin :refs/hidden/22", is rejected. This is not a new restriction. To the pusher, it would appear that there is no such ref, so its push request will conclude with "Now that I sent you all the data, it is time for you to update the refs. I saw that the ref did not exist when I started pushing, and I want the result to point at this commit". The receiving end will apply the compare-and-swap rule to this request and rejects the push with "Well, your update request conflicts with somebody else; I see there is such a ref.", which is the right thing to do. Otherwise a push to a hidden ref will always be "the last one wins", which is not a good default. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-01-19 04:08:30 +04:00
done
refs: support negative transfer.hideRefs If you hide a hierarchy of refs using the transfer.hideRefs config, there is no way to later override that config to "unhide" it. This patch implements a "negative" hide which causes matches to immediately be marked as unhidden, even if another match would hide it. We take care to apply the matches in reverse-order from how they are fed to us by the config machinery, as that lets our usual "last one wins" config precedence work (and entries in .git/config, for example, will override /etc/gitconfig). So you can now do: $ git config --system transfer.hideRefs refs/secret $ git config transfer.hideRefs '!refs/secret/not-so-secret' to hide refs/secret in all repos, except for one public bit in one specific repo. Or you can even do: $ git clone \ -u "git -c transfer.hiderefs="!refs/foo" upload-pack" \ remote:repo.git to clone remote:repo.git, overriding any hiding it has configured. There are two alternatives that were considered and rejected: 1. A generic config mechanism for removing an item from a list. E.g.: (e.g., "[transfer] hideRefs -= refs/foo"). This is nice because it could apply to other multi-valued config, as well. But it is not nearly as flexible. There is no way to say: [transfer] hideRefs = refs/secret hideRefs = refs/secret/not-so-secret Having explicit negative specifications means we can override previous entries, even if they are not the same literal string. 2. Adding another variable to override some parts of hideRefs (e.g., "exposeRefs"). This solves the problem from alternative (1), but it cannot easily obey the normal config precedence, because it would use two separate lists. For example: [transfer] hideRefs = refs/secret exposeRefs = refs/secret/not-so-secret hideRefs = refs/secret/not-so-secret/no-really-its-secret With two lists, we have to apply the "expose" rules first, and only then apply the "hide" rules. But that does not match what the above config intends. Of course we could internally parse that to a single list, respecting the ordering, which saves us having to invent the new "!" syntax. But using a single name communicates to the user that the ordering _is_ important. And "!" is well-known for negation, and should not appear at the beginning of a ref (it is actually valid in a ref-name, but all entries here should be fully-qualified, starting with "refs/"). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-07-28 23:23:26 +03:00
test_expect_success 'overrides work between mixed transfer/upload-pack hideRefs' '
test_config uploadpack.hiderefs refs/tags &&
test_config transfer.hiderefs "!refs/tags/magic" &&
git ls-remote . >actual &&
grep refs/tags/magic actual
'
test_expect_success 'protocol v2 supports hiderefs' '
test_config uploadpack.hiderefs refs/tags &&
git -c protocol.version=2 ls-remote . >actual &&
! grep refs/tags actual
'
test_expect_success 'ls-remote --symref' '
git fetch origin &&
cat >expect <<-EOF &&
ref: refs/heads/master HEAD
$(git rev-parse HEAD) HEAD
$(git rev-parse refs/heads/master) refs/heads/master
$(git rev-parse HEAD) refs/remotes/origin/HEAD
$(git rev-parse refs/remotes/origin/master) refs/remotes/origin/master
$(git rev-parse refs/tags/mark) refs/tags/mark
$(git rev-parse refs/tags/mark1.1) refs/tags/mark1.1
$(git rev-parse refs/tags/mark1.10) refs/tags/mark1.10
$(git rev-parse refs/tags/mark1.2) refs/tags/mark1.2
EOF
# Protocol v2 supports sending symrefs for refs other than HEAD, so use
# protocol v0 here.
GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref >actual &&
test_cmp expect actual
'
test_expect_success 'ls-remote with filtered symref (refname)' '
rev=$(git rev-parse HEAD) &&
cat >expect <<-EOF &&
ref: refs/heads/master HEAD
$rev HEAD
EOF
# Protocol v2 supports sending symrefs for refs other than HEAD, so use
# protocol v0 here.
GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref . HEAD >actual &&
test_cmp expect actual
'
test_expect_failure 'ls-remote with filtered symref (--heads)' '
git symbolic-ref refs/heads/foo refs/tags/mark &&
cat >expect <<-EOF &&
ref: refs/tags/mark refs/heads/foo
$rev refs/heads/foo
$rev refs/heads/master
EOF
# Protocol v2 supports sending symrefs for refs other than HEAD, so use
# protocol v0 here.
GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref --heads . >actual &&
test_cmp expect actual
'
test_expect_success 'ls-remote --symref omits filtered-out matches' '
cat >expect <<-EOF &&
$rev refs/heads/foo
$rev refs/heads/master
EOF
# Protocol v2 supports sending symrefs for refs other than HEAD, so use
# protocol v0 here.
GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref --heads . >actual &&
test_cmp expect actual &&
GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref . "refs/heads/*" >actual &&
test_cmp expect actual
'
connect: advertized capability is not a ref When cloning an empty repository served by standard git, "git clone" produces the following reassuring message: $ git clone git://localhost/tmp/empty Cloning into 'empty'... warning: You appear to have cloned an empty repository. Checking connectivity... done. Meanwhile when cloning an empty repository served by JGit, the output is more haphazard: $ git clone git://localhost/tmp/empty Cloning into 'empty'... Checking connectivity... done. warning: remote HEAD refers to nonexistent ref, unable to checkout. This is a common command to run immediately after creating a remote repository as preparation for adding content to populate it and pushing. The warning is confusing and needlessly worrying. The cause is that, since v3.1.0.201309270735-rc1~22 (Advertise capabilities with no refs in upload service., 2013-08-08), JGit's ref advertisement includes a ref named capabilities^{} to advertise its capabilities on, while git's ref advertisement is empty in this case. This allows the client to learn about the server's capabilities and is needed, for example, for fetch-by-sha1 to work when no refs are advertised. This also affects "ls-remote". For example, against an empty repository served by JGit: $ git ls-remote git://localhost/tmp/empty 0000000000000000000000000000000000000000 capabilities^{} Git advertises the same capabilities^{} ref in its ref advertisement for push but since it never did so for fetch, the client didn't need to handle this case. Handle it. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Helped-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-09-09 20:36:30 +03:00
test_lazy_prereq GIT_DAEMON '
tests: add 'test_bool_env' to catch non-bool GIT_TEST_* values Since 3b072c577b (tests: replace test_tristate with "git env--helper", 2019-06-21) we get the normalized bool values of various GIT_TEST_* environment variables via 'git env--helper'. Now, while the 'git env--helper' command itself does catch invalid values in the environment variable or in the given --default and exits with error (exit code 128 or 129, respectively), it's invoked in conditions like 'if ! git env--helper ...', which means that all invalid bool values are interpreted the same as the ordinary 'false' (exit code 1). This has led to inadvertently skipped httpd tests in our CI builds for a couple of weeks, see 3960290675 (ci: restore running httpd tests, 2019-09-06). Let's be more careful about what the test suite accepts as bool values in GIT_TEST_* environment variables, and error out loud and clear on invalid values instead of simply skipping tests. Add the 'test_bool_env' helper function to encapsulate the invocation of 'git env--helper' and the verification of its exit code, and replace all invocations of that command in our test framework and test suite with a call to this new helper (except in 't0017-env-helper.sh', of course). $ GIT_TEST_GIT_DAEMON=YesPlease ./t5570-git-daemon.sh fatal: bad numeric config value 'YesPlease' for 'GIT_TEST_GIT_DAEMON': invalid unit error: test_bool_env requires bool values both for $GIT_TEST_GIT_DAEMON and for the default fallback Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-11-22 16:14:36 +03:00
test_bool_env GIT_TEST_GIT_DAEMON true
connect: advertized capability is not a ref When cloning an empty repository served by standard git, "git clone" produces the following reassuring message: $ git clone git://localhost/tmp/empty Cloning into 'empty'... warning: You appear to have cloned an empty repository. Checking connectivity... done. Meanwhile when cloning an empty repository served by JGit, the output is more haphazard: $ git clone git://localhost/tmp/empty Cloning into 'empty'... Checking connectivity... done. warning: remote HEAD refers to nonexistent ref, unable to checkout. This is a common command to run immediately after creating a remote repository as preparation for adding content to populate it and pushing. The warning is confusing and needlessly worrying. The cause is that, since v3.1.0.201309270735-rc1~22 (Advertise capabilities with no refs in upload service., 2013-08-08), JGit's ref advertisement includes a ref named capabilities^{} to advertise its capabilities on, while git's ref advertisement is empty in this case. This allows the client to learn about the server's capabilities and is needed, for example, for fetch-by-sha1 to work when no refs are advertised. This also affects "ls-remote". For example, against an empty repository served by JGit: $ git ls-remote git://localhost/tmp/empty 0000000000000000000000000000000000000000 capabilities^{} Git advertises the same capabilities^{} ref in its ref advertisement for push but since it never did so for fetch, the client didn't need to handle this case. Handle it. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Helped-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-09-09 20:36:30 +03:00
'
# This test spawns a daemon, so run it only if the user would be OK with
# testing with git-daemon.
test_expect_success PIPE,JGIT,GIT_DAEMON 'indicate no refs in standards-compliant empty remote' '
test-lib-functions: introduce the 'test_set_port' helper function Several test scripts run daemons like 'git-daemon' or Apache, and communicate with them through TCP sockets. To have unique ports where these daemons are accessible, the ports are usually the number of the corresponding test scripts, unless the user overrides them via environment variables, and thus all those tests and test libs contain more or less the same bit of one-liner boilerplate code to find out the port. The last patch in this series will make this a bit more complicated. Factor out finding the port for a daemon into the common helper function 'test_set_port' to avoid repeating ourselves. Take special care of test scripts with "low" numbers: - Test numbers below 1024 would result in a port that's only usable as root, so set their port to '10000 + test-nr' to make sure it doesn't interfere with other tests in the test suite. This makes the hardcoded port number in 't0410-partial-clone.sh' unnecessary, remove it. - The shell's arithmetic evaluation interprets numbers with leading zeros as octal values, which means that test number below 1000 and containing the digits 8 or 9 will trigger an error. Remove all leading zeros from the test numbers to prevent this. Note that the 'git p4' tests are unlike the other tests involving daemons in that: - 'lib-git-p4.sh' doesn't use the test's number for unique port as is, but does a bit of additional arithmetic on top [1]. - The port is not overridable via an environment variable. With this patch even 'git p4' tests will use the test's number as default port, and it will be overridable via the P4DPORT environment variable. [1] Commit fc00233071 (git-p4 tests: refactor and cleanup, 2011-08-22) introduced that "unusual" unique port computation without explaining why it was necessary (as opposed to simply using the test number as is). It seems to be just unnecessary complication, and in any case that commit came way before the "test nr as unique port" got "standardized" for other daemons in commits c44132fcf3 (tests: auto-set git-daemon port, 2014-02-10), 3bb486e439 (tests: auto-set LIB_HTTPD_PORT from test name, 2014-02-10), and bf9d7df950 (t/lib-git-svn.sh: improve svnserve tests with parallel make test, 2017-12-01). Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-05 04:08:58 +03:00
test_set_port JGIT_DAEMON_PORT &&
connect: advertized capability is not a ref When cloning an empty repository served by standard git, "git clone" produces the following reassuring message: $ git clone git://localhost/tmp/empty Cloning into 'empty'... warning: You appear to have cloned an empty repository. Checking connectivity... done. Meanwhile when cloning an empty repository served by JGit, the output is more haphazard: $ git clone git://localhost/tmp/empty Cloning into 'empty'... Checking connectivity... done. warning: remote HEAD refers to nonexistent ref, unable to checkout. This is a common command to run immediately after creating a remote repository as preparation for adding content to populate it and pushing. The warning is confusing and needlessly worrying. The cause is that, since v3.1.0.201309270735-rc1~22 (Advertise capabilities with no refs in upload service., 2013-08-08), JGit's ref advertisement includes a ref named capabilities^{} to advertise its capabilities on, while git's ref advertisement is empty in this case. This allows the client to learn about the server's capabilities and is needed, for example, for fetch-by-sha1 to work when no refs are advertised. This also affects "ls-remote". For example, against an empty repository served by JGit: $ git ls-remote git://localhost/tmp/empty 0000000000000000000000000000000000000000 capabilities^{} Git advertises the same capabilities^{} ref in its ref advertisement for push but since it never did so for fetch, the client didn't need to handle this case. Handle it. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Helped-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-09-09 20:36:30 +03:00
JGIT_DAEMON_PID= &&
git init --bare empty.git &&
>empty.git/git-daemon-export-ok &&
mkfifo jgit_daemon_output &&
{
jgit daemon --port="$JGIT_DAEMON_PORT" . >jgit_daemon_output &
JGIT_DAEMON_PID=$!
} &&
test_when_finished kill "$JGIT_DAEMON_PID" &&
{
read line &&
case $line in
Exporting*)
;;
*)
echo "Expected: Exporting" &&
false;;
esac &&
read line &&
case $line in
"Listening on"*)
;;
*)
echo "Expected: Listening on" &&
false;;
esac
} <jgit_daemon_output &&
# --exit-code asks the command to exit with 2 when no
# matching refs are found.
test_expect_code 2 git ls-remote --exit-code git://localhost:$JGIT_DAEMON_PORT/empty.git
'
test_expect_success 'ls-remote works outside repository' '
# It is important for this repo to be inside the nongit
# area, as we want a repo name that does not include
# slashes (because those inhibit some of our configuration
# lookups).
nongit git init --bare dst.git &&
nongit git ls-remote dst.git
'
test_expect_success 'ls-remote --sort fails gracefully outside repository' '
# Use a sort key that requires access to the referenced objects.
nongit test_must_fail git ls-remote --sort=authordate "$TRASH_DIRECTORY" 2>err &&
test_i18ngrep "^fatal: not a git repository, but the field '\''authordate'\'' requires access to object data" err
'
test_expect_success 'ls-remote patterns work with all protocol versions' '
git for-each-ref --format="%(objectname) %(refname)" \
refs/heads/master refs/remotes/origin/master >expect &&
git -c protocol.version=1 ls-remote . master >actual.v1 &&
test_cmp expect actual.v1 &&
git -c protocol.version=2 ls-remote . master >actual.v2 &&
test_cmp expect actual.v2
'
test_expect_success 'ls-remote prefixes work with all protocol versions' '
git for-each-ref --format="%(objectname) %(refname)" \
refs/heads/ refs/tags/ >expect &&
git -c protocol.version=1 ls-remote --heads --tags . >actual.v1 &&
test_cmp expect actual.v1 &&
git -c protocol.version=2 ls-remote --heads --tags . >actual.v2 &&
test_cmp expect actual.v2
'
test_done