diff --git a/ref-filter.c b/ref-filter.c index 1da4c0e60d..9b04e3af85 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -3316,15 +3316,14 @@ static int do_filter_refs(struct ref_filter *filter, unsigned int type, refs_for if (prefix) { struct ref_iterator *iter; + struct ref_store *store = get_main_ref_store(the_repository); - iter = refs_ref_iterator_begin(get_main_ref_store(the_repository), - "", NULL, 0, 0); - - if (filter->start_after) + if (filter->start_after) { + iter = refs_ref_iterator_begin(store, "", NULL, 0, 0); ret = start_ref_iterator_after(iter, filter->start_after); - else - ret = ref_iterator_seek(iter, prefix, - REF_ITERATOR_SEEK_SET_PREFIX); + } else { + iter = refs_ref_iterator_begin(store, prefix, NULL, 0, 0); + } if (!ret) ret = do_for_each_ref_iterator(iter, fn, cb_data); diff --git a/t/perf/p6300-for-each-ref.sh b/t/perf/p6300-for-each-ref.sh index fa7289c752..25ffa5e84c 100755 --- a/t/perf/p6300-for-each-ref.sh +++ b/t/perf/p6300-for-each-ref.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='performance of for-each-ref' +test_description='performance of ref-filter users' . ./perf-lib.sh test_perf_fresh_repo @@ -84,4 +84,41 @@ test_expect_success 'pack refs' ' ' run_tests "packed" +test_expect_success 'setup many unrelated refs' ' + git init scoped && + test_commit -C scoped --no-tag base && + test_seq $ref_count_per_type | + sed "s,.*,update refs/custom/unrelated_& HEAD," | + git -C scoped update-ref --stdin && + git -C scoped update-ref refs/remotes/origin/main HEAD && + git -C scoped update-ref refs/tags/only HEAD +' + +test_perf "branch (many unrelated refs)" " + ( + cd scoped && + for i in \$(test_seq $test_iteration_count); do + git branch --format='%(refname)' >/dev/null + done + ) +" + +test_perf "branch --remotes (many unrelated refs)" " + ( + cd scoped && + for i in \$(test_seq $test_iteration_count); do + git branch --remotes --format='%(refname)' >/dev/null + done + ) +" + +test_perf "tag (many unrelated refs)" " + ( + cd scoped && + for i in \$(test_seq $test_iteration_count); do + git tag --format='%(refname)' >/dev/null + done + ) +" + test_done