return !!resolve_ref_unsafe(refname, RESOLVE_REF_READING, NULL, NULL);
}
+static int match_ref_pattern(const char *refname,
+ const struct string_list_item *item)
+{
+ int matched = 0;
+ if (item->util == NULL) {
+ if (!wildmatch(item->string, refname, 0))
+ matched = 1;
+ } else {
+ const char *rest;
+ if (skip_prefix(refname, item->string, &rest) &&
+ (!*rest || *rest == '/'))
+ matched = 1;
+ }
+ return matched;
+}
+
+int ref_filter_match(const char *refname,
+ const struct string_list *include_patterns,
+ const struct string_list *exclude_patterns)
+{
+ struct string_list_item *item;
+
+ if (exclude_patterns && exclude_patterns->nr) {
+ for_each_string_list_item(item, exclude_patterns) {
+ if (match_ref_pattern(refname, item))
+ return 0;
+ }
+ }
+
+ if (include_patterns && include_patterns->nr) {
+ int found = 0;
+ for_each_string_list_item(item, include_patterns) {
+ if (match_ref_pattern(refname, item)) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found)
+ return 0;
+ }
+ return 1;
+}
+
static int filter_refs(const char *refname, const struct object_id *oid,
int flags, void *data)
{
return ret;
}
+void normalize_glob_ref(struct string_list_item *item, const char *prefix,
+ const char *pattern)
+{
+ struct strbuf normalized_pattern = STRBUF_INIT;
+
+ if (*pattern == '/')
+ BUG("pattern must not start with '/'");
+
+ if (prefix) {
+ strbuf_addstr(&normalized_pattern, prefix);
+ }
+ else if (!starts_with(pattern, "refs/"))
+ strbuf_addstr(&normalized_pattern, "refs/");
+ strbuf_addstr(&normalized_pattern, pattern);
+ strbuf_strip_suffix(&normalized_pattern, "/");
+
+ item->string = strbuf_detach(&normalized_pattern, NULL);
+ item->util = has_glob_specials(pattern) ? NULL : item->string;
+ strbuf_release(&normalized_pattern);
+}
+
int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
const char *prefix, void *cb_data)
{