mirror of
https://github.com/git/git
synced 2024-08-28 12:09:19 +00:00
![Junio C Hamano](/assets/img/avatar_default.png)
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>
142 lines
3.5 KiB
Bash
Executable file
142 lines
3.5 KiB
Bash
Executable file
#!/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 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 '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_must_fail 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' '
|
|
cat >exp <<-\EOF &&
|
|
fatal: '\''refs*master'\'' 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 refs*master >actual 2>&1 &&
|
|
test_cmp exp actual
|
|
'
|
|
|
|
test_expect_success 'die with non-2 for wrong repository even with --exit-code' '
|
|
git ls-remote --exit-code ./no-such-repository ;# not &&
|
|
status=$? &&
|
|
test $status != 2 && test $status != 0
|
|
'
|
|
|
|
test_expect_success 'Report success even when nothing matches' '
|
|
git ls-remote other.git "refs/nsn/*" >actual &&
|
|
>expect &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'Report no-match with --exit-code' '
|
|
test_expect_code 2 git ls-remote --exit-code other.git "refs/nsn/*" >actual &&
|
|
>expect &&
|
|
test_cmp expect 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
|
|
'
|
|
|
|
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
|
|
'
|
|
done
|
|
|
|
test_done
|