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
This commit is contained in:
@ -366,6 +366,13 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
|
|||||||
struct commit_name **slot;
|
struct commit_name **slot;
|
||||||
|
|
||||||
seen_commits++;
|
seen_commits++;
|
||||||
|
|
||||||
|
if (match_cnt == max_candidates ||
|
||||||
|
match_cnt == hashmap_get_size(&names)) {
|
||||||
|
gave_up_on = c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
slot = commit_names_peek(&commit_names, c);
|
slot = commit_names_peek(&commit_names, c);
|
||||||
n = slot ? *slot : NULL;
|
n = slot ? *slot : NULL;
|
||||||
if (n) {
|
if (n) {
|
||||||
@ -381,10 +388,6 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
|
|||||||
if (n->prio == 2)
|
if (n->prio == 2)
|
||||||
annotated_cnt++;
|
annotated_cnt++;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
gave_up_on = c;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (cur_match = 0; cur_match < match_cnt; cur_match++) {
|
for (cur_match = 0; cur_match < match_cnt; cur_match++) {
|
||||||
struct possible_tag *t = &all_matches[cur_match];
|
struct possible_tag *t = &all_matches[cur_match];
|
||||||
@ -470,9 +473,8 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
|
|||||||
fprintf(stderr, _("traversed %lu commits\n"), seen_commits);
|
fprintf(stderr, _("traversed %lu commits\n"), seen_commits);
|
||||||
if (gave_up_on) {
|
if (gave_up_on) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
_("more than %i tags found; listed %i most recent\n"
|
_("found %i tags; gave up search at %s\n"),
|
||||||
"gave up search at %s\n"),
|
max_candidates,
|
||||||
max_candidates, max_candidates,
|
|
||||||
oid_to_hex(&gave_up_on->object.oid));
|
oid_to_hex(&gave_up_on->object.oid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
30
t/perf/p6100-describe.sh
Executable file
30
t/perf/p6100-describe.sh
Executable file
@ -0,0 +1,30 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
test_description='performance of git-describe'
|
||||||
|
. ./perf-lib.sh
|
||||||
|
|
||||||
|
test_perf_default_repo
|
||||||
|
|
||||||
|
# clear out old tags and give us a known state
|
||||||
|
test_expect_success 'set up tags' '
|
||||||
|
git for-each-ref --format="delete %(refname)" refs/tags >to-delete &&
|
||||||
|
git update-ref --stdin <to-delete &&
|
||||||
|
new=$(git rev-list -1000 HEAD | tail -n 1) &&
|
||||||
|
git tag -m new new $new &&
|
||||||
|
old=$(git rev-list HEAD | tail -n 1) &&
|
||||||
|
git tag -m old old $old
|
||||||
|
'
|
||||||
|
|
||||||
|
test_perf 'describe HEAD' '
|
||||||
|
git describe HEAD
|
||||||
|
'
|
||||||
|
|
||||||
|
test_perf 'describe HEAD with one max candidate' '
|
||||||
|
git describe --candidates=1 HEAD
|
||||||
|
'
|
||||||
|
|
||||||
|
test_perf 'describe HEAD with one tag' '
|
||||||
|
git describe --match=new HEAD
|
||||||
|
'
|
||||||
|
|
||||||
|
test_done
|
@ -18,6 +18,7 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|||||||
|
|
||||||
check_describe () {
|
check_describe () {
|
||||||
indir= &&
|
indir= &&
|
||||||
|
outcome=success &&
|
||||||
while test $# != 0
|
while test $# != 0
|
||||||
do
|
do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
@ -25,6 +26,9 @@ check_describe () {
|
|||||||
indir="$2"
|
indir="$2"
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
--expect-failure)
|
||||||
|
outcome=failure
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
@ -35,7 +39,7 @@ check_describe () {
|
|||||||
expect="$1"
|
expect="$1"
|
||||||
shift
|
shift
|
||||||
describe_opts="$@"
|
describe_opts="$@"
|
||||||
test_expect_success "describe $describe_opts" '
|
test_expect_${outcome} "describe $describe_opts" '
|
||||||
git ${indir:+ -C "$indir"} describe $describe_opts >raw &&
|
git ${indir:+ -C "$indir"} describe $describe_opts >raw &&
|
||||||
sed -e "s/-g[0-9a-f]*\$/-gHASH/" <raw >actual &&
|
sed -e "s/-g[0-9a-f]*\$/-gHASH/" <raw >actual &&
|
||||||
echo "$expect" >expect &&
|
echo "$expect" >expect &&
|
||||||
@ -616,7 +620,7 @@ test_expect_success 'name-rev --annotate-stdin works with commitGraph' '
|
|||||||
|
|
||||||
# B
|
# B
|
||||||
# o
|
# o
|
||||||
# \
|
# H \
|
||||||
# o-----o---o----x
|
# o-----o---o----x
|
||||||
# A
|
# A
|
||||||
#
|
#
|
||||||
@ -626,6 +630,7 @@ test_expect_success 'setup: describe commits with disjoint bases' '
|
|||||||
cd disjoint1 &&
|
cd disjoint1 &&
|
||||||
|
|
||||||
echo o >> file && git add file && git commit -m o &&
|
echo o >> file && git add file && git commit -m o &&
|
||||||
|
git tag H -a -m H &&
|
||||||
echo A >> file && git add file && git commit -m A &&
|
echo A >> file && git add file && git commit -m A &&
|
||||||
git tag A -a -m A &&
|
git tag A -a -m A &&
|
||||||
echo o >> file && git add file && git commit -m o &&
|
echo o >> file && git add file && git commit -m o &&
|
||||||
@ -638,8 +643,9 @@ test_expect_success 'setup: describe commits with disjoint bases' '
|
|||||||
'
|
'
|
||||||
|
|
||||||
check_describe -C disjoint1 "A-3-gHASH" HEAD
|
check_describe -C disjoint1 "A-3-gHASH" HEAD
|
||||||
|
check_describe -C disjoint1 --expect-failure "A-3-gHASH" --candidates=2 HEAD
|
||||||
|
|
||||||
# B
|
# H B
|
||||||
# o---o---o------------.
|
# o---o---o------------.
|
||||||
# \
|
# \
|
||||||
# o---o---x
|
# o---o---x
|
||||||
@ -657,6 +663,7 @@ test_expect_success 'setup: describe commits with disjoint bases 2' '
|
|||||||
git checkout --orphan branch &&
|
git checkout --orphan branch &&
|
||||||
echo o >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:00" git commit -m o &&
|
echo o >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:00" git commit -m o &&
|
||||||
echo o >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:01" git commit -m o &&
|
echo o >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:01" git commit -m o &&
|
||||||
|
git tag H -a -m H &&
|
||||||
echo B >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:02" git commit -m B &&
|
echo B >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:02" git commit -m B &&
|
||||||
git tag B -a -m B &&
|
git tag B -a -m B &&
|
||||||
git merge --no-ff --allow-unrelated-histories main -m x
|
git merge --no-ff --allow-unrelated-histories main -m x
|
||||||
@ -664,6 +671,7 @@ test_expect_success 'setup: describe commits with disjoint bases 2' '
|
|||||||
'
|
'
|
||||||
|
|
||||||
check_describe -C disjoint2 "B-3-gHASH" HEAD
|
check_describe -C disjoint2 "B-3-gHASH" HEAD
|
||||||
|
check_describe -C disjoint2 --expect-failure "B-3-gHASH" --candidates=2 HEAD
|
||||||
|
|
||||||
test_expect_success 'setup misleading taggerdates' '
|
test_expect_success 'setup misleading taggerdates' '
|
||||||
GIT_COMMITTER_DATE="2006-12-12 12:31" git tag -a -m "another tag" newer-tag-older-commit unique-file~1
|
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' '
|
|||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success '--always with no refs falls back to commit hash' '
|
||||||
|
git rev-parse HEAD >expect &&
|
||||||
|
git describe --no-abbrev --always --match=no-such-tag >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '--exact-match does not show --always fallback' '
|
||||||
|
test_must_fail git describe --exact-match --always
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
Reference in New Issue
Block a user