Skip to content

Commit c482315

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 f7c4c41 + b8150bf commit c482315

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
@@ -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

0 commit comments

Comments
 (0)