Skip to content

Commit 73b7e03

Browse files
committed
Merge branch 'jk/describe-perf'
"git describe" optimization. * jk/describe-perf: describe: split "found all tags" and max_candidates logic 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 2ccc89b + db16286 commit 73b7e03

File tree

3 files changed

+60
-10
lines changed

3 files changed

+60
-10
lines changed

builtin/describe.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,13 @@ 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+
match_cnt == hashmap_get_size(&names)) {
372+
gave_up_on = c;
373+
break;
374+
}
375+
369376
slot = commit_names_peek(&commit_names, c);
370377
n = slot ? *slot : NULL;
371378
if (n) {
@@ -381,10 +388,6 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
381388
if (n->prio == 2)
382389
annotated_cnt++;
383390
}
384-
else {
385-
gave_up_on = c;
386-
break;
387-
}
388391
}
389392
for (cur_match = 0; cur_match < match_cnt; cur_match++) {
390393
struct possible_tag *t = &all_matches[cur_match];
@@ -470,9 +473,8 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
470473
fprintf(stderr, _("traversed %lu commits\n"), seen_commits);
471474
if (gave_up_on) {
472475
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,
476+
_("found %i tags; gave up search at %s\n"),
477+
max_candidates,
476478
oid_to_hex(&gave_up_on->object.oid));
477479
}
478480
}

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: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,17 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
1818

1919
check_describe () {
2020
indir= &&
21+
outcome=success &&
2122
while test $# != 0
2223
do
2324
case "$1" in
2425
-C)
2526
indir="$2"
2627
shift
2728
;;
29+
--expect-failure)
30+
outcome=failure
31+
;;
2832
*)
2933
break
3034
;;
@@ -35,7 +39,7 @@ check_describe () {
3539
expect="$1"
3640
shift
3741
describe_opts="$@"
38-
test_expect_success "describe $describe_opts" '
42+
test_expect_${outcome} "describe $describe_opts" '
3943
git ${indir:+ -C "$indir"} describe $describe_opts >raw &&
4044
sed -e "s/-g[0-9a-f]*\$/-gHASH/" <raw >actual &&
4145
echo "$expect" >expect &&
@@ -616,7 +620,7 @@ test_expect_success 'name-rev --annotate-stdin works with commitGraph' '
616620

617621
# B
618622
# o
619-
# \
623+
# H \
620624
# o-----o---o----x
621625
# A
622626
#
@@ -626,6 +630,7 @@ test_expect_success 'setup: describe commits with disjoint bases' '
626630
cd disjoint1 &&
627631
628632
echo o >> file && git add file && git commit -m o &&
633+
git tag H -a -m H &&
629634
echo A >> file && git add file && git commit -m A &&
630635
git tag A -a -m A &&
631636
echo o >> file && git add file && git commit -m o &&
@@ -638,8 +643,9 @@ test_expect_success 'setup: describe commits with disjoint bases' '
638643
'
639644

640645
check_describe -C disjoint1 "A-3-gHASH" HEAD
646+
check_describe -C disjoint1 --expect-failure "A-3-gHASH" --candidates=2 HEAD
641647

642-
# B
648+
# H B
643649
# o---o---o------------.
644650
# \
645651
# o---o---x
@@ -657,13 +663,15 @@ test_expect_success 'setup: describe commits with disjoint bases 2' '
657663
git checkout --orphan branch &&
658664
echo o >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:00" git commit -m o &&
659665
echo o >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:01" git commit -m o &&
666+
git tag H -a -m H &&
660667
echo B >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:02" git commit -m B &&
661668
git tag B -a -m B &&
662669
git merge --no-ff --allow-unrelated-histories main -m x
663670
)
664671
'
665672

666673
check_describe -C disjoint2 "B-3-gHASH" HEAD
674+
check_describe -C disjoint2 --expect-failure "B-3-gHASH" --candidates=2 HEAD
667675

668676
test_expect_success 'setup misleading taggerdates' '
669677
GIT_COMMITTER_DATE="2006-12-12 12:31" git tag -a -m "another tag" newer-tag-older-commit unique-file~1
@@ -707,4 +715,14 @@ test_expect_success 'describe --broken --dirty with a file with changed stat' '
707715
)
708716
'
709717

718+
test_expect_success '--always with no refs falls back to commit hash' '
719+
git rev-parse HEAD >expect &&
720+
git describe --no-abbrev --always --match=no-such-tag >actual &&
721+
test_cmp expect actual
722+
'
723+
724+
test_expect_success '--exact-match does not show --always fallback' '
725+
test_must_fail git describe --exact-match --always
726+
'
727+
710728
test_done

0 commit comments

Comments
 (0)