From: Jeff King <peff@peff.net>
To: git@vger.kernel.org
Subject: [PATCH 2/2] refs: support negative transfer.hideRefs
Date: Tue, 28 Jul 2015 15:59:34 -0400 [thread overview]
Message-ID: <20150728195934.GB13795@peff.net> (raw)
In-Reply-To: <20150728195747.GA13596@peff.net>
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).
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>
---
Documentation/config.txt | 5 +++++
refs.c | 18 +++++++++++++-----
t/t5512-ls-remote.sh | 15 +++++++++++++++
3 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 448eb9d..a7fbd0a 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -2540,6 +2540,11 @@ transfer.hideRefs::
excluded, and is hidden when responding to `git push` or `git
fetch`. See `receive.hideRefs` and `uploadpack.hideRefs` for
program-specific versions of this config.
++
+You may also include a `!` in front of the ref name to negate the entry,
+explicitly exposing it, even if an earlier entry marked it as hidden.
+If you have multiple hideRefs values, later entries override earlier ones
+(and entries in more-specific config files override less-specific ones).
transfer.unpackLimit::
When `fetch.unpackLimit` or `receive.unpackLimit` are
diff --git a/refs.c b/refs.c
index 7ac05cf..68f2cb0 100644
--- a/refs.c
+++ b/refs.c
@@ -4159,17 +4159,25 @@ int parse_hide_refs_config(const char *var, const char *value, const char *secti
int ref_is_hidden(const char *refname)
{
- struct string_list_item *item;
+ int i;
if (!hide_refs)
return 0;
- for_each_string_list_item(item, hide_refs) {
+ for (i = hide_refs->nr - 1; i >= 0; i--) {
+ const char *match = hide_refs->items[i].string;
+ int neg = 0;
int len;
- if (!starts_with(refname, item->string))
+
+ if (*match == '!') {
+ neg = 1;
+ match++;
+ }
+
+ if (!starts_with(refname, match))
continue;
- len = strlen(item->string);
+ len = strlen(match);
if (!refname[len] || refname[len] == '/')
- return 1;
+ return !neg;
}
return 0;
}
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index 3bd9759..728a1dc 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -128,6 +128,11 @@ test_expect_success 'Report match with --exit-code' '
test_cmp expect actual
'
+test_expect_success 'set up some extra tags for ref hiding' '
+ git tag magic/one &&
+ git tag magic/two
+'
+
for configsection in transfer uploadpack
do
test_expect_success "Hide some refs with $configsection.hiderefs" '
@@ -138,6 +143,16 @@ do
sed -e "/ refs\/tags\//d" >expect &&
test_cmp expect actual
'
+
+ 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 &&
+ verbose grep refs/tags/magic/two actual
+ '
+
done
test_done
--
2.5.0.rc3.557.g17a1555
next prev parent reply other threads:[~2015-07-28 19:59 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-28 19:57 [PATCH 0/2] negative hideRefs for overriding Jeff King
2015-07-28 19:59 ` [PATCH 1/2] docs/config.txt: reorder hideRefs config Jeff King
2015-07-28 19:59 ` Jeff King [this message]
2015-07-28 20:14 ` [PATCH 2/2] refs: support negative transfer.hideRefs Junio C Hamano
2015-07-28 20:23 ` Jeff King
2015-07-30 20:17 ` Eric Sunshine
2015-07-30 23:28 ` Jeff King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150728195934.GB13795@peff.net \
--to=peff@peff.net \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.