]> git.ipfire.org Git - thirdparty/git.git/commitdiff
describe: limit default ref iteration to tags
authorTamir Duberstein <tamird@gmail.com>
Wed, 10 Jun 2026 18:50:01 +0000 (11:50 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 10 Jun 2026 19:38:49 +0000 (12:38 -0700)
Without --all, git describe ignores refs outside refs/tags/. Commit
8a5a1884e9 (Avoid accessing non-tag refs in git-describe unless --all is
requested, 2008-02-24) moved this check ahead of object lookup. That
avoided loading objects for irrelevant refs, but the backend still has
to yield every ref before get_name() can reject it.

Pass refs/tags/ to the iterator so the backend can avoid visiting those
refs in the first place.

The new perf test creates 10,000 unrelated packed refs. It measures:

    git describe --exact-match HEAD

The runtime drops from 0.03(0.01+0.01) to 0.02(0.00+0.00). In a
repository with 120,532 refs but only 330 tags, the same command went
from 171.7 ms to 9.9 ms.

Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/describe.c
t/perf/p6100-describe.sh

index bffeed13a3cb14d7ce738597460c29556fe8aa2a..e93c3720ec4bd79f4313ef2e9423cb49f321cd9d 100644 (file)
@@ -740,6 +740,9 @@ int cmd_describe(int argc,
                return ret;
        }
 
+       if (!all)
+               for_each_ref_opts.prefix = "refs/tags/";
+
        hashmap_init(&names, commit_name_neq, NULL, 0);
        refs_for_each_ref_ext(get_main_ref_store(the_repository),
                              get_name, NULL, &for_each_ref_opts);
index 069f91ce493a703c95a88244f3e58e26e017f44c..b1c61529bb7bf8ff64c15ae42576774b5d05fabf 100755 (executable)
@@ -27,4 +27,16 @@ test_perf 'describe HEAD with one tag' '
        git describe --match=new HEAD
 '
 
+test_expect_success 'set up many unrelated refs' '
+       ref_count=10000 &&
+       git tag -m tip tip HEAD &&
+       test_seq -f "create refs/heads/describe-perf/%05d HEAD" $ref_count |
+       git update-ref --stdin &&
+       git pack-refs --all
+'
+
+test_perf 'describe exact tag with many unrelated refs' '
+       git describe --exact-match HEAD
+'
+
 test_done