refs.h: implement `hidden_refs_to_excludes()`

In subsequent commits, we'll teach `receive-pack` and `upload-pack` to
use the new jump list feature in the packed-refs iterator by ignoring
references which are mentioned via its respective hideRefs lists.

However, the packed-ref jump lists cannot handle un-hiding rules (that
begin with '!'), or namespace comparisons (that begin with '^'). Add a
convenience function to the refs.h API to detect when either of these
conditions are met, and returns an appropriate value to pass as excluded
patterns.

Suggested-by: Jeff King <peff@peff.net>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Taylor Blau 2023-07-10 17:12:39 -04:00 committed by Junio C Hamano
parent e6bf24d39a
commit 15af64dcfd
2 changed files with 30 additions and 0 deletions

24
refs.c
View File

@ -1480,6 +1480,30 @@ int ref_is_hidden(const char *refname, const char *refname_full,
return 0;
}

const char **hidden_refs_to_excludes(const struct strvec *hide_refs)
{
const char **pattern;
for (pattern = hide_refs->v; *pattern; pattern++) {
/*
* We can't feed any excludes from hidden refs config
* sections, since later rules may override previous
* ones. For example, with rules "refs/foo" and
* "!refs/foo/bar", we should show "refs/foo/bar" (and
* everything underneath it), but the earlier exclusion
* would cause us to skip all of "refs/foo". We
* likewise don't implement the namespace stripping
* required for '^' rules.
*
* Both are possible to do, but complicated, so avoid
* populating the jump list at all if we see either of
* these patterns.
*/
if (**pattern == '!' || **pattern == '^')
return NULL;
}
return hide_refs->v;
}

const char *find_descendant_ref(const char *dirname,
const struct string_list *extras,
const struct string_list *skip)

6
refs.h
View File

@ -831,6 +831,12 @@ int parse_hide_refs_config(const char *var, const char *value, const char *,
*/
int ref_is_hidden(const char *, const char *, const struct strvec *);

/*
* Returns an array of patterns to use as excluded_patterns, if none of the
* hidden references use the token '!' or '^'.
*/
const char **hidden_refs_to_excludes(const struct strvec *hide_refs);

/* Is this a per-worktree ref living in the refs/ namespace? */
int is_per_worktree_ref(const char *refname);