+static const char *match_ref_pattern = NULL;
+static int match_ref_slash = 0;
+static int count_slash(const char *s)
+{
+ int cnt = 0;
+ while (*s)
+ if (*s++ == '/')
+ cnt++;
+ return cnt;
+}
+
+static int append_matching_ref(const char *refname, const unsigned char *sha1)
+{
+ /* we want to allow pattern hold/<asterisk> to show all
+ * branches under refs/heads/hold/, and v0.99.9? to show
+ * refs/tags/v0.99.9a and friends.
+ */
+ const char *tail;
+ int slash = count_slash(refname);
+ for (tail = refname; *tail && match_ref_slash < slash; )
+ if (*tail++ == '/')
+ slash--;
+ if (!*tail)
+ return 0;
+ if (fnmatch(match_ref_pattern, tail, 0))
+ return 0;
+ if (!strncmp("refs/heads/", refname, 11))
+ return append_head_ref(refname, sha1);
+ if (!strncmp("refs/tags/", refname, 10))
+ return append_tag_ref(refname, sha1);
+ return append_ref(refname, sha1);
+}
+