diff --git a/refs.c b/refs.c index 95a7db9563..75cd6695eb 100644 --- a/refs.c +++ b/refs.c @@ -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) diff --git a/refs.h b/refs.h index 7152e0a09f..a8924d374c 100644 --- a/refs.h +++ b/refs.h @@ -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);