Skip to content

Commit f821025

Browse files
committed
Merge branch 'jk/describe-perf' into seen
"git describe" optimization. * jk/describe-perf: describe: stop traversing when we run out of names describe: stop digging for max_candidates+1 t/perf: add tests for git-describe t6120: demonstrate weakness in disjoint-root handling
2 parents f638992 + b8150bf commit f821025

File tree

3 files changed

+51
-10
lines changed

3 files changed

+51
-10
lines changed

builtin/describe.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,12 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
366366
struct commit_name **slot;
367367

368368
seen_commits++;
369+
370+
if (match_cnt == max_candidates) {
371+
gave_up_on = c;
372+
break;
373+
}
374+
369375
slot = commit_names_peek(&commit_names, c);
370376
n = slot ? *slot : NULL;
371377
if (n) {
@@ -381,10 +387,6 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
381387
if (n->prio == 2)
382388
annotated_cnt++;
383389
}
384-
else {
385-
gave_up_on = c;
386-
break;
387-
}
388390
}
389391
for (cur_match = 0; cur_match < match_cnt; cur_match++) {
390392
struct possible_tag *t = &all_matches[cur_match];
@@ -470,9 +472,8 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
470472
fprintf(stderr, _("traversed %lu commits\n"), seen_commits);
471473
if (gave_up_on) {
472474
fprintf(stderr,
473-
_("more than %i tags found; listed %i most recent\n"
474-
"gave up search at %s\n"),
475-
max_candidates, max_candidates,
475+
_("found %i tags; gave up search at %s\n"),
476+
max_candidates,
476477
oid_to_hex(&gave_up_on->object.oid));
477478
}
478479
}
@@ -666,6 +667,8 @@ int cmd_describe(int argc,
666667
NULL);
667668
if (!hashmap_get_size(&names) && !always)
668669
die(_("No names found, cannot describe anything."));
670+
if (hashmap_get_size(&names) < max_candidates)
671+
max_candidates = hashmap_get_size(&names);
669672

670673
if (argc == 0) {
671674
if (broken) {

t/perf/p6100-describe.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/bin/sh
2+
3+
test_description='performance of git-describe'
4+
. ./perf-lib.sh
5+
6+
test_perf_default_repo
7+
8+
# clear out old tags and give us a known state
9+
test_expect_success 'set up tags' '
10+
git for-each-ref --format="delete %(refname)" refs/tags >to-delete &&
11+
git update-ref --stdin <to-delete &&
12+
new=$(git rev-list -1000 HEAD | tail -n 1) &&
13+
git tag -m new new $new &&
14+
old=$(git rev-list HEAD | tail -n 1) &&
15+
git tag -m old old $old
16+
'
17+
18+
test_perf 'describe HEAD' '
19+
git describe HEAD
20+
'
21+
22+
test_perf 'describe HEAD with one max candidate' '
23+
git describe --candidates=1 HEAD
24+
'
25+
26+
test_perf 'describe HEAD with one tag' '
27+
git describe --match=new HEAD
28+
'
29+
30+
test_done

t/t6120-describe.sh

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,17 @@ TEST_PASSES_SANITIZE_LEAK=true
1919

2020
check_describe () {
2121
indir= &&
22+
outcome=success &&
2223
while test $# != 0
2324
do
2425
case "$1" in
2526
-C)
2627
indir="$2"
2728
shift
2829
;;
30+
--expect-failure)
31+
outcome=failure
32+
;;
2933
*)
3034
break
3135
;;
@@ -36,7 +40,7 @@ check_describe () {
3640
expect="$1"
3741
shift
3842
describe_opts="$@"
39-
test_expect_success "describe $describe_opts" '
43+
test_expect_${outcome} "describe $describe_opts" '
4044
git ${indir:+ -C "$indir"} describe $describe_opts >raw &&
4145
sed -e "s/-g[0-9a-f]*\$/-gHASH/" <raw >actual &&
4246
echo "$expect" >expect &&
@@ -617,7 +621,7 @@ test_expect_success 'name-rev --annotate-stdin works with commitGraph' '
617621

618622
# B
619623
# o
620-
# \
624+
# H \
621625
# o-----o---o----x
622626
# A
623627
#
@@ -627,6 +631,7 @@ test_expect_success 'setup: describe commits with disjoint bases' '
627631
cd disjoint1 &&
628632
629633
echo o >> file && git add file && git commit -m o &&
634+
git tag H -a -m H &&
630635
echo A >> file && git add file && git commit -m A &&
631636
git tag A -a -m A &&
632637
echo o >> file && git add file && git commit -m o &&
@@ -639,8 +644,9 @@ test_expect_success 'setup: describe commits with disjoint bases' '
639644
'
640645

641646
check_describe -C disjoint1 "A-3-gHASH" HEAD
647+
check_describe -C disjoint1 --expect-failure "A-3-gHASH" --candidates=2 HEAD
642648

643-
# B
649+
# H B
644650
# o---o---o------------.
645651
# \
646652
# o---o---x
@@ -658,13 +664,15 @@ test_expect_success 'setup: describe commits with disjoint bases 2' '
658664
git checkout --orphan branch &&
659665
echo o >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:00" git commit -m o &&
660666
echo o >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:01" git commit -m o &&
667+
git tag H -a -m H &&
661668
echo B >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:02" git commit -m B &&
662669
git tag B -a -m B &&
663670
git merge --no-ff --allow-unrelated-histories main -m x
664671
)
665672
'
666673

667674
check_describe -C disjoint2 "B-3-gHASH" HEAD
675+
check_describe -C disjoint2 --expect-failure "B-3-gHASH" --candidates=2 HEAD
668676

669677
test_expect_success 'setup misleading taggerdates' '
670678
GIT_COMMITTER_DATE="2006-12-12 12:31" git tag -a -m "another tag" newer-tag-older-commit unique-file~1

0 commit comments

Comments
 (0)