2007-11-07 02:29:20 +01:00
|
|
|
#!/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 &&
|
2018-04-09 03:42:26 +02:00
|
|
|
git tag mark1.1 &&
|
|
|
|
git tag mark1.2 &&
|
|
|
|
git tag mark1.10 &&
|
2007-11-07 02:29:20 +01:00
|
|
|
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 &&
|
|
|
|
|
2008-05-04 07:37:59 +02:00
|
|
|
git remote add self "$(pwd)/.git"
|
2007-11-07 02:29:20 +01:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'ls-remote --tags .git' '
|
|
|
|
git ls-remote --tags .git >actual &&
|
2008-03-12 22:36:36 +01:00
|
|
|
test_cmp expected.tag actual
|
2007-11-07 02:29:20 +01:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'ls-remote .git' '
|
|
|
|
git ls-remote .git >actual &&
|
2008-03-12 22:36:36 +01:00
|
|
|
test_cmp expected.all actual
|
2007-11-07 02:29:20 +01:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'ls-remote --tags self' '
|
|
|
|
git ls-remote --tags self >actual &&
|
2008-03-12 22:36:36 +01:00
|
|
|
test_cmp expected.tag actual
|
2007-11-07 02:29:20 +01:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'ls-remote self' '
|
|
|
|
git ls-remote self >actual &&
|
2008-03-12 22:36:36 +01:00
|
|
|
test_cmp expected.all actual
|
2007-11-07 02:29:20 +01:00
|
|
|
'
|
|
|
|
|
2018-04-09 03:42:26 +02:00
|
|
|
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
|
|
|
|
'
|
|
|
|
|
ls-remote: fall-back to default remotes when no remote specified
Instead of breaking execution when no remote (as specified in the
variable dest) is specified when git-ls-remote is invoked, continue on
and let remote_get() handle it.
This way, we are able to use the default remotes (eg. "origin",
branch.<name>.remote), as git-fetch, git-push, and other users of
remote_get(), do.
If no suitable remote is found, exit with a message describing the
issue, instead of just the usage text, as we do previously.
Add several tests to check that git-ls-remote handles the
no-remote-specified situation.
Also add a test that "git ls-remote <pattern>" does not work; we are
unable to guess the remote in that situation, as are git-fetch and
git-push.
In that test, we are testing for messages coming from two separate
processes, but we should be OK, because the second message is triggered
by closing the fd which must happen after the first message is printed.
(analysis by Jeff King.)
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-04-08 19:21:13 +02:00
|
|
|
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' '
|
2010-05-11 19:20:23 +02:00
|
|
|
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 &&
|
ls-remote: fall-back to default remotes when no remote specified
Instead of breaking execution when no remote (as specified in the
variable dest) is specified when git-ls-remote is invoked, continue on
and let remote_get() handle it.
This way, we are able to use the default remotes (eg. "origin",
branch.<name>.remote), as git-fetch, git-push, and other users of
remote_get(), do.
If no suitable remote is found, exit with a message describing the
issue, instead of just the usage text, as we do previously.
Add several tests to check that git-ls-remote handles the
no-remote-specified situation.
Also add a test that "git ls-remote <pattern>" does not work; we are
unable to guess the remote in that situation, as are git-fetch and
git-push.
In that test, we are testing for messages coming from two separate
processes, but we should be OK, because the second message is triggered
by closing the fd which must happen after the first message is printed.
(analysis by Jeff King.)
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-04-08 19:21:13 +02:00
|
|
|
test_cmp expected.all actual
|
|
|
|
'
|
|
|
|
|
2010-05-11 19:20:23 +02:00
|
|
|
test_expect_success 'suppress "From <url>" with -q' '
|
|
|
|
git ls-remote -q 2>actual_err &&
|
|
|
|
test_must_fail test_cmp exp_err actual_err
|
|
|
|
'
|
|
|
|
|
ls-remote: fall-back to default remotes when no remote specified
Instead of breaking execution when no remote (as specified in the
variable dest) is specified when git-ls-remote is invoked, continue on
and let remote_get() handle it.
This way, we are able to use the default remotes (eg. "origin",
branch.<name>.remote), as git-fetch, git-push, and other users of
remote_get(), do.
If no suitable remote is found, exit with a message describing the
issue, instead of just the usage text, as we do previously.
Add several tests to check that git-ls-remote handles the
no-remote-specified situation.
Also add a test that "git ls-remote <pattern>" does not work; we are
unable to guess the remote in that situation, as are git-fetch and
git-push.
In that test, we are testing for messages coming from two separate
processes, but we should be OK, because the second message is triggered
by closing the fd which must happen after the first message is printed.
(analysis by Jeff King.)
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-04-08 19:21:13 +02:00
|
|
|
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 &&
|
|
|
|
|
2010-05-11 19:20:23 +02:00
|
|
|
URL="other.git" &&
|
|
|
|
echo "From $URL" >exp_err &&
|
|
|
|
|
|
|
|
git remote add other $URL &&
|
ls-remote: fall-back to default remotes when no remote specified
Instead of breaking execution when no remote (as specified in the
variable dest) is specified when git-ls-remote is invoked, continue on
and let remote_get() handle it.
This way, we are able to use the default remotes (eg. "origin",
branch.<name>.remote), as git-fetch, git-push, and other users of
remote_get(), do.
If no suitable remote is found, exit with a message describing the
issue, instead of just the usage text, as we do previously.
Add several tests to check that git-ls-remote handles the
no-remote-specified situation.
Also add a test that "git ls-remote <pattern>" does not work; we are
unable to guess the remote in that situation, as are git-fetch and
git-push.
In that test, we are testing for messages coming from two separate
processes, but we should be OK, because the second message is triggered
by closing the fd which must happen after the first message is printed.
(analysis by Jeff King.)
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-04-08 19:21:13 +02:00
|
|
|
git config branch.master.remote other &&
|
|
|
|
|
2010-05-11 19:20:23 +02:00
|
|
|
git ls-remote 2>actual_err >actual &&
|
|
|
|
test_cmp exp_err actual_err &&
|
ls-remote: fall-back to default remotes when no remote specified
Instead of breaking execution when no remote (as specified in the
variable dest) is specified when git-ls-remote is invoked, continue on
and let remote_get() handle it.
This way, we are able to use the default remotes (eg. "origin",
branch.<name>.remote), as git-fetch, git-push, and other users of
remote_get(), do.
If no suitable remote is found, exit with a message describing the
issue, instead of just the usage text, as we do previously.
Add several tests to check that git-ls-remote handles the
no-remote-specified situation.
Also add a test that "git ls-remote <pattern>" does not work; we are
unable to guess the remote in that situation, as are git-fetch and
git-push.
In that test, we are testing for messages coming from two separate
processes, but we should be OK, because the second message is triggered
by closing the fd which must happen after the first message is printed.
(analysis by Jeff King.)
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-04-08 19:21:13 +02:00
|
|
|
test_cmp exp actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'confuses pattern as remote when no remote specified' '
|
2017-05-03 12:16:50 +02:00
|
|
|
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
|
2012-07-05 08:40:11 +02:00
|
|
|
fatal: Could not read from remote repository.
|
|
|
|
|
|
|
|
Please make sure you have the correct access rights
|
|
|
|
and the repository exists.
|
2012-03-03 03:15:34 +01:00
|
|
|
EOF
|
ls-remote: fall-back to default remotes when no remote specified
Instead of breaking execution when no remote (as specified in the
variable dest) is specified when git-ls-remote is invoked, continue on
and let remote_get() handle it.
This way, we are able to use the default remotes (eg. "origin",
branch.<name>.remote), as git-fetch, git-push, and other users of
remote_get(), do.
If no suitable remote is found, exit with a message describing the
issue, instead of just the usage text, as we do previously.
Add several tests to check that git-ls-remote handles the
no-remote-specified situation.
Also add a test that "git ls-remote <pattern>" does not work; we are
unable to guess the remote in that situation, as are git-fetch and
git-push.
In that test, we are testing for messages coming from two separate
processes, but we should be OK, because the second message is triggered
by closing the fd which must happen after the first message is printed.
(analysis by Jeff King.)
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-04-08 19:21:13 +02:00
|
|
|
#
|
2012-06-19 20:24:50 +02:00
|
|
|
# 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>.
|
ls-remote: fall-back to default remotes when no remote specified
Instead of breaking execution when no remote (as specified in the
variable dest) is specified when git-ls-remote is invoked, continue on
and let remote_get() handle it.
This way, we are able to use the default remotes (eg. "origin",
branch.<name>.remote), as git-fetch, git-push, and other users of
remote_get(), do.
If no suitable remote is found, exit with a message describing the
issue, instead of just the usage text, as we do previously.
Add several tests to check that git-ls-remote handles the
no-remote-specified situation.
Also add a test that "git ls-remote <pattern>" does not work; we are
unable to guess the remote in that situation, as are git-fetch and
git-push.
In that test, we are testing for messages coming from two separate
processes, but we should be OK, because the second message is triggered
by closing the fd which must happen after the first message is printed.
(analysis by Jeff King.)
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-04-08 19:21:13 +02:00
|
|
|
# We could just as easily have used "master"; the "*" emphasizes its
|
|
|
|
# role as a pattern.
|
2017-05-03 12:16:50 +02:00
|
|
|
test_must_fail git ls-remote "$does_not_exist" >actual 2>&1 &&
|
2016-09-19 15:08:17 +02:00
|
|
|
test_i18ncmp exp actual
|
ls-remote: fall-back to default remotes when no remote specified
Instead of breaking execution when no remote (as specified in the
variable dest) is specified when git-ls-remote is invoked, continue on
and let remote_get() handle it.
This way, we are able to use the default remotes (eg. "origin",
branch.<name>.remote), as git-fetch, git-push, and other users of
remote_get(), do.
If no suitable remote is found, exit with a message describing the
issue, instead of just the usage text, as we do previously.
Add several tests to check that git-ls-remote handles the
no-remote-specified situation.
Also add a test that "git ls-remote <pattern>" does not work; we are
unable to guess the remote in that situation, as are git-fetch and
git-push.
In that test, we are testing for messages coming from two separate
processes, but we should be OK, because the second message is triggered
by closing the fd which must happen after the first message is printed.
(analysis by Jeff King.)
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-04-08 19:21:13 +02:00
|
|
|
'
|
|
|
|
|
2011-05-18 22:06:00 +02:00
|
|
|
test_expect_success 'die with non-2 for wrong repository even with --exit-code' '
|
2015-03-20 11:12:29 +01:00
|
|
|
{
|
|
|
|
git ls-remote --exit-code ./no-such-repository
|
|
|
|
status=$?
|
|
|
|
} &&
|
2011-05-18 22:06:00 +02:00
|
|
|
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 &&
|
2018-04-09 03:42:26 +02:00
|
|
|
git ls-remote . tags/mark* >expect &&
|
2011-05-18 22:06:00 +02:00
|
|
|
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 22:23:26 +02: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 01:08:30 +01: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 22:23:26 +02: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 01:08:30 +01: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 22:23:26 +02: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
|
|
|
|
'
|
|
|
|
|
2016-01-19 00:20:50 +01:00
|
|
|
test_expect_success 'ls-remote --symref' '
|
2018-05-12 10:45:23 +02:00
|
|
|
git fetch origin &&
|
2018-04-09 03:42:26 +02:00
|
|
|
cat >expect <<-EOF &&
|
2016-01-19 00:20:50 +01:00
|
|
|
ref: refs/heads/master HEAD
|
2018-04-09 03:42:26 +02:00
|
|
|
$(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
|
2016-01-19 00:20:50 +01:00
|
|
|
EOF
|
|
|
|
git ls-remote --symref >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'ls-remote with filtered symref (refname)' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
ref: refs/heads/master HEAD
|
|
|
|
1bd44cb9d13204b0fe1958db0082f5028a16eb3a HEAD
|
|
|
|
EOF
|
|
|
|
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
|
|
|
|
1bd44cb9d13204b0fe1958db0082f5028a16eb3a refs/heads/foo
|
|
|
|
1bd44cb9d13204b0fe1958db0082f5028a16eb3a refs/heads/master
|
|
|
|
EOF
|
|
|
|
git ls-remote --symref --heads . >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'ls-remote --symref omits filtered-out matches' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
1bd44cb9d13204b0fe1958db0082f5028a16eb3a refs/heads/foo
|
|
|
|
1bd44cb9d13204b0fe1958db0082f5028a16eb3a refs/heads/master
|
|
|
|
EOF
|
|
|
|
git ls-remote --symref --heads . >actual &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
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 19:36:30 +02:00
|
|
|
test_lazy_prereq GIT_DAEMON '
|
|
|
|
test_tristate GIT_TEST_GIT_DAEMON &&
|
|
|
|
test "$GIT_TEST_GIT_DAEMON" != false
|
|
|
|
'
|
|
|
|
|
|
|
|
# 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' '
|
|
|
|
JGIT_DAEMON_PORT=${JGIT_DAEMON_PORT-${this_test#t}} &&
|
|
|
|
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
|
|
|
|
'
|
2016-01-19 00:20:50 +01:00
|
|
|
|
2017-02-14 21:33:28 +01:00
|
|
|
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
|
|
|
|
'
|
|
|
|
|
2007-11-07 02:29:20 +01:00
|
|
|
test_done
|