On Thu, Oct 31, 2024 at 11:37 AM Rasmus Villemoes <ravi@xxxxxxxxx> wrote: > > On Wed, Oct 30 2024, Josh Poimboeuf <jpoimboe@xxxxxxxxxx> wrote: > > > If HEAD isn't associated with an annotated tag, a bug (or feature?) in > > "git describe --match" causes it to search every commit in the entire > > repository looking for additional match candidates. Instead of it > > taking a fraction of a second, it adds 10-15 seconds to the beginning of > > every kernel build. > > > > Fix it by adding an additional dummy match which is slightly further > > away from the most recent one, along with setting the max candidate > > count to 1 (not 2, apparently another bug). > > > > cc += git list > > Hm, I tried looking at the git describe source code, and while I can't > claim I understand it very well, I think the main problem is around > this part: > > if (!tags && !all && n->prio < 2) { > unannotated_cnt++; > } else if (match_cnt < max_candidates) { > struct possible_tag *t = &all_matches[match_cnt++]; > t->name = n; > t->depth = seen_commits - 1; > t->flag_within = 1u << match_cnt; > t->found_order = match_cnt; > c->object.flags |= t->flag_within; > if (n->prio == 2) > annotated_cnt++; > } > else { > gave_up_on = c; > break; > } > > So in the case where one doesn't pass any --match, we get something like > > git describe --debug 5f78aec0d7e9 > describe 5f78aec0d7e9 > No exact match on refs or tags, searching to describe > annotated 243 v4.19-rc5 > annotated 485 v4.19-rc4 > annotated 814 v4.19-rc3 > annotated 1124 v4.19-rc2 > annotated 1391 v4.19-rc1 > annotated 10546 v4.18 > annotated 10611 v4.18-rc8 > annotated 10819 v4.18-rc7 > annotated 11029 v4.18-rc6 > annotated 11299 v4.18-rc5 > traversed 11400 commits > more than 10 tags found; listed 10 most recent > gave up search at 1e4b044d22517cae7047c99038abb444423243ca > v4.19-rc5-243-g5f78aec0d7e9 > > and that "gave up" commit is v4.18-rc4, the eleventh commit > encountered. That also explains why you have to add a "dummy" second > --match to make --candidates=1 have the expected behaviour. > > Perhaps the logic should instead be that as soon as match_cnt hits > max_candidates (i.e. all the tags we're going to consider have actually > been visited), we break out. That is, the last "else" above should > instead be replaced by > > if (match_cnt == max_candidates) { > ... /* ? , gave_up_on is now a misnomer */ > break; > } > > Then as a further DWIM aid, wherever the initialization logic is could > be updated so that, after expanding all the --match= wildcards, if the > number of tags is less than max_candidates, automatically lower > max_candidates to that number (which in the setlocalversion case will > always be 1 because we're not actually passing a wildcard). > > Or, we could explicitly on the kernel side pass that --candidates=1, but > yes, I agree it looks like a bug that the loop requires encountering +1 > tag to hit that break;. > > Rasmus > I still do not understand the logic either. git traverses all the way back to d8470b7c13e11c18cf14a7e3180f0b00e715e4f0. $ git describe --match=v6.12-rc5 --debug c1e939a21eb1 describe c1e939a21eb1 No exact match on refs or tags, searching to describe finished search at d8470b7c13e11c18cf14a7e3180f0b00e715e4f0 annotated 44 v6.12-rc5 traversed 1310005 commits v6.12-rc5-44-gc1e939a21eb1 Or, more simply, $ git describe --match=v6.12-rc5 --debug e42b1a9a2557 describe e42b1a9a2557 No exact match on refs or tags, searching to describe finished search at d8470b7c13e11c18cf14a7e3180f0b00e715e4f0 annotated 5 v6.12-rc5 traversed 1309966 commits v6.12-rc5-5-ge42b1a9a2557 e42b1a9a2557 merges v6.12-rc5 and 25f00a13dccf. The latter is obviously, v6.12-rc2 + 4 commits. v6.12-rc2 is an ancestor of v6.12-rc5. I do not understand why git traverses 1.3 million commits. -- Best Regards Masahiro Yamada