]> git.ipfire.org Git - thirdparty/git.git/blobdiff - t/t5512-ls-remote.sh
tests: teach callers of test_i18ngrep to use test_grep
[thirdparty/git.git] / t / t5512-ls-remote.sh
index f53f58895a12979f27a1b24ba9f15ee37bbc49a9..5dbe107ce88f98e75341d5ba3b25ae4f8d10d35f 100755 (executable)
@@ -15,6 +15,23 @@ generate_references () {
        done
 }
 
+test_expect_success 'set up fake upload-pack' '
+       # This can be used to simulate an upload-pack that just shows the
+       # contents of the "input" file (prepared with the test-tool pkt-line
+       # helper), and does not do any negotiation (since ls-remote does not
+       # need it).
+       write_script cat-input <<-\EOF
+       # send our initial advertisement/response
+       cat input
+       # soak up the flush packet from the client
+       cat
+       EOF
+'
+
+test_expect_success 'dies when no remote found' '
+       test_must_fail git ls-remote
+'
+
 test_expect_success setup '
        >file &&
        git add file &&
@@ -30,7 +47,8 @@ test_expect_success setup '
        git show-ref -d >refs &&
        sed -e "s/ /    /" refs >>expected.all &&
 
-       git remote add self "$(pwd)/.git"
+       git remote add self "$(pwd)/.git" &&
+       git remote add self2 "."
 '
 
 test_expect_success 'ls-remote --tags .git' '
@@ -83,11 +101,17 @@ test_expect_success 'ls-remote --sort="-refname" --tags self' '
        test_cmp expect actual
 '
 
-test_expect_success 'dies when no remote specified and no default remotes found' '
+test_expect_success 'dies when no remote specified, multiple remotes found, and no default specified' '
        test_must_fail git ls-remote
 '
 
-test_expect_success 'use "origin" when no remote specified' '
+test_expect_success 'succeeds when no remote specified but only one found' '
+       test_when_finished git remote add self2 "." &&
+       git remote remove self2 &&
+       git ls-remote
+'
+
+test_expect_success 'use "origin" when no remote specified and multiple found' '
        URL="$(pwd)/.git" &&
        echo "From $URL" >exp_err &&
 
@@ -220,22 +244,25 @@ test_expect_success 'protocol v2 supports hiderefs' '
 
 test_expect_success 'ls-remote --symref' '
        git fetch origin &&
-       echo "ref: refs/heads/main      HEAD" >expect &&
+       echo "ref: refs/heads/main      HEAD" >expect.v2 &&
        generate_references \
                HEAD \
-               refs/heads/main >>expect &&
+               refs/heads/main >>expect.v2 &&
+       echo "ref: refs/remotes/origin/main     refs/remotes/origin/HEAD" >>expect.v2 &&
        oid=$(git rev-parse HEAD) &&
-       echo "$oid      refs/remotes/origin/HEAD" >>expect &&
+       echo "$oid      refs/remotes/origin/HEAD" >>expect.v2 &&
        generate_references \
                refs/remotes/origin/main \
                refs/tags/mark \
                refs/tags/mark1.1 \
                refs/tags/mark1.10 \
-               refs/tags/mark1.2 >>expect &&
-       # 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
+               refs/tags/mark1.2 >>expect.v2 &&
+       # v0 does not show non-HEAD symrefs
+       grep -v "ref: refs/remotes" <expect.v2 >expect.v0 &&
+       git -c protocol.version=0 ls-remote --symref >actual.v0 &&
+       test_cmp expect.v0 actual.v0 &&
+       git -c protocol.version=2 ls-remote --symref >actual.v2 &&
+       test_cmp expect.v2 actual.v2
 '
 
 test_expect_success 'ls-remote with filtered symref (refname)' '
@@ -244,76 +271,41 @@ test_expect_success 'ls-remote with filtered symref (refname)' '
        ref: refs/heads/main    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 &&
+       git ls-remote --symref . HEAD >actual &&
        test_cmp expect actual
 '
 
-test_expect_failure 'ls-remote with filtered symref (--heads)' '
+test_expect_success 'ls-remote with filtered symref (--heads)' '
        git symbolic-ref refs/heads/foo refs/tags/mark &&
-       cat >expect <<-EOF &&
+       cat >expect.v2 <<-EOF &&
        ref: refs/tags/mark     refs/heads/foo
        $rev    refs/heads/foo
        $rev    refs/heads/main
        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
+       grep -v "^ref: refs/tags/" <expect.v2 >expect.v0 &&
+       git -c protocol.version=0 ls-remote --symref --heads . >actual.v0 &&
+       test_cmp expect.v0 actual.v0 &&
+       git -c protocol.version=2 ls-remote --symref --heads . >actual.v2 &&
+       test_cmp expect.v2 actual.v2
 '
 
-test_expect_success 'ls-remote --symref omits filtered-out matches' '
-       cat >expect <<-EOF &&
-       $rev    refs/heads/foo
-       $rev    refs/heads/main
+test_expect_success 'indicate no refs in v0 standards-compliant empty remote' '
+       # Git does not produce an output like this, but it does match the
+       # standard and is produced by other implementations like JGit. So
+       # hard-code the case we care about.
+       #
+       # The actual capabilities do not matter; there are none that would
+       # change how ls-remote behaves.
+       oid=0000000000000000000000000000000000000000 &&
+       test-tool pkt-line pack >input.q <<-EOF &&
+       $oid capabilities^{}Qcaps-go-here
+       0000
        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
-'
-
-test_lazy_prereq GIT_DAEMON '
-       test_bool_env GIT_TEST_GIT_DAEMON true
-'
+       q_to_nul <input.q >input &&
 
-# 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_set_port JGIT_DAEMON_PORT &&
-       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_code 2 git ls-remote --exit-code --upload-pack=./cat-input .
 '
 
 test_expect_success 'ls-remote works outside repository' '
@@ -328,14 +320,14 @@ test_expect_success 'ls-remote works outside repository' '
 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_grep "^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/main refs/remotes/origin/main >expect &&
-       git -c protocol.version=1 ls-remote . main >actual.v1 &&
-       test_cmp expect actual.v1 &&
+       git -c protocol.version=0 ls-remote . main >actual.v0 &&
+       test_cmp expect actual.v0 &&
        git -c protocol.version=2 ls-remote . main >actual.v2 &&
        test_cmp expect actual.v2
 '
@@ -343,10 +335,49 @@ test_expect_success 'ls-remote patterns work with all protocol versions' '
 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=0 ls-remote --heads --tags . >actual.v0 &&
+       test_cmp expect actual.v0 &&
        git -c protocol.version=2 ls-remote --heads --tags . >actual.v2 &&
        test_cmp expect actual.v2
 '
 
+test_expect_success 'v0 clients can handle multiple symrefs' '
+       # Modern versions of Git will not return multiple symref capabilities
+       # for v0, so we have to hard-code the response. Note that we will
+       # always use both v0 and object-format=sha1 here, as the hard-coded
+       # response reflects a server that only supports those.
+       oid=1234567890123456789012345678901234567890 &&
+       symrefs="symref=refs/remotes/origin/HEAD:refs/remotes/origin/main" &&
+       symrefs="$symrefs symref=HEAD:refs/heads/main" &&
+
+       # Likewise we want to make sure our parser is not fooled by the string
+       # "symref" appearing as part of an earlier cap. But there is no way to
+       # do that via upload-pack, as arbitrary strings can appear only in a
+       # "symref" value itself (where we skip past the values as a whole)
+       # and "agent" (which always appears after "symref", so putting our
+       # parser in a confused state is less interesting).
+       caps="some other caps including a-fake-symref-cap" &&
+
+       test-tool pkt-line pack >input.q <<-EOF &&
+       $oid HEADQ$caps $symrefs
+       $oid refs/heads/main
+       $oid refs/remotes/origin/HEAD
+       $oid refs/remotes/origin/main
+       0000
+       EOF
+       q_to_nul <input.q >input &&
+
+       cat >expect <<-EOF &&
+       ref: refs/heads/main    HEAD
+       $oid    HEAD
+       $oid    refs/heads/main
+       ref: refs/remotes/origin/main   refs/remotes/origin/HEAD
+       $oid    refs/remotes/origin/HEAD
+       $oid    refs/remotes/origin/main
+       EOF
+
+       git ls-remote --symref --upload-pack=./cat-input . >actual &&
+       test_cmp expect actual
+'
+
 test_done