444
/* The argument to for_each_filter_refs */
445
struct for_each_ref_filter {
446
const char *pattern;
447
- const char *prefix;
447
+ size_t trim_prefix;
448
refs_for_each_cb *fn;
449
void *cb_data;
450
};
475
476
if (wildmatch(filter->pattern, ref->name, 0))
477
return 0;
478
- if (filter->prefix) {
478
+ if (filter->trim_prefix) {
479
struct reference skipped = *ref;
480
- skip_prefix(skipped.name, filter->prefix, &skipped.name);
480
+ if (strlen(skipped.name) <= filter->trim_prefix)
481
+ BUG("attempt to trim too many characters");
482
+ skipped.name += filter->trim_prefix;
483
return filter->fn(&skipped, filter->cb_data);
484
} else {
485
return filter->fn(ref, filter->cb_data);
592
strbuf_release(&normalized_pattern);
593
}
594
593
-int refs_for_each_glob_ref_in(struct ref_store *refs, refs_for_each_cb fn,
595
+int refs_for_each_glob_ref_in(struct ref_store *refs, refs_for_each_cb cb,
596
const char *pattern, const char *prefix, void *cb_data)
597
{
596
- struct strbuf real_pattern = STRBUF_INIT;
597
- struct for_each_ref_filter filter;
598
- int ret;
599
-
600
- if (!prefix && !starts_with(pattern, "refs/"))
601
- strbuf_addstr(&real_pattern, "refs/");
602
- else if (prefix)
603
- strbuf_addstr(&real_pattern, prefix);
604
- strbuf_addstr(&real_pattern, pattern);
605
-
606
- if (!has_glob_specials(pattern)) {
607
- /* Append implied '/' '*' if not present. */
608
- strbuf_complete(&real_pattern, '/');
609
- /* No need to check for '*', there is none. */
610
- strbuf_addch(&real_pattern, '*');
611
- }
612
-
613
- filter.pattern = real_pattern.buf;
614
- filter.prefix = prefix;
615
- filter.fn = fn;
616
- filter.cb_data = cb_data;
617
- ret = refs_for_each_ref(refs, for_each_filter_refs, &filter);
618
-
619
- strbuf_release(&real_pattern);
620
- return ret;
598
+ struct refs_for_each_ref_options opts = {
599
+ .pattern = pattern,
600
+ .prefix = prefix,
601
+ .trim_prefix = prefix ? strlen(prefix) : 0,
602
+ };
603
+ return refs_for_each_ref_ext(refs, cb, cb_data, &opts);
604
}
605
623
-int refs_for_each_glob_ref(struct ref_store *refs, refs_for_each_cb fn,
606
+int refs_for_each_glob_ref(struct ref_store *refs, refs_for_each_cb cb,
607
const char *pattern, void *cb_data)
608
{
626
- return refs_for_each_glob_ref_in(refs, fn, pattern, NULL, cb_data);
609
+ struct refs_for_each_ref_options opts = {
610
+ .pattern = pattern,
611
+ };
612
+ return refs_for_each_ref_ext(refs, cb, cb_data, &opts);
613
}
614
615
const char *prettify_refname(const char *name)
1848
refs_for_each_cb cb, void *cb_data,
1849
const struct refs_for_each_ref_options *opts)
1850
{
1851
+ struct strbuf real_pattern = STRBUF_INIT;
1852
+ struct for_each_ref_filter filter;
1853
struct ref_iterator *iter;
1854
+ size_t trim_prefix = opts->trim_prefix;
1855
+ int ret;
1856
1857
if (!refs)
1858
return 0;
1859
1860
+ if (opts->pattern) {
1861
+ if (!opts->prefix && !starts_with(opts->pattern, "refs/"))
1862
+ strbuf_addstr(&real_pattern, "refs/");
1863
+ else if (opts->prefix)
1864
+ strbuf_addstr(&real_pattern, opts->prefix);
1865
+ strbuf_addstr(&real_pattern, opts->pattern);
1866
+
1867
+ if (!has_glob_specials(opts->pattern)) {
1868
+ /* Append implied '/' '*' if not present. */
1869
+ strbuf_complete(&real_pattern, '/');
1870
+ /* No need to check for '*', there is none. */
1871
+ strbuf_addch(&real_pattern, '*');
1872
+ }
1873
+
1874
+ filter.pattern = real_pattern.buf;
1875
+ filter.trim_prefix = opts->trim_prefix;
1876
+ filter.fn = cb;
1877
+ filter.cb_data = cb_data;
1878
+
1879
+ /*
1880
+ * We need to trim the prefix in the callback function as the
1881
+ * pattern is expected to match on the full refname.
1882
+ */
1883
+ trim_prefix = 0;
1884
+
1885
+ cb = for_each_filter_refs;
1886
+ cb_data = &filter;
1887
+ }
1888
+
1889
iter = refs_ref_iterator_begin(refs, opts->prefix ? opts->prefix : "",
1890
opts->exclude_patterns,
1872
- opts->trim_prefix, opts->flags);
1891
+ trim_prefix, opts->flags);
1892
1874
- return do_for_each_ref_iterator(iter, cb, cb_data);
1893
+ ret = do_for_each_ref_iterator(iter, cb, cb_data);
1894
+ strbuf_release(&real_pattern);
1895
+ return ret;
1896
}
1897
1898
int refs_for_each_ref(struct ref_store *refs, refs_for_each_cb cb, void *cb_data)