git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] setlocalversion: Add workaround for "git describe" performance issue

From
Jeff King <peff@peff.net>
Date
Nov 1, 2024, 11:39 UTC
Message-ID
<20241101113910.GA2301440@coredump.intra.peff.net>
In-Reply-To
<8734kbjlrq.fsf@prevas.dk>
On Fri, Nov 01, 2024 at 11:23:05AM +0100, Rasmus Villemoes wrote:
> Perhaps we could on the kernel side replace the "git describe --match"
> calls with a helper, something like this (needs a lot of polishing):

Yeah, if you are describing off of a single tag, it may just be easier to query things about the tag directly. Though I do still think git-describe should be faster here. I'm still pondering what to do about the disjoint history tests, but otherwise have a polished series to send.

Show 12 quoted lines
> ===
> # Produce output similar to what "git describe --match=$tag 2>
> # /dev/null" would.  It doesn't have to match exactly as the caller is
> # only interested in whether $tag == HEAD, and if not, the number
> # between the tag and the short sha1.
> describe()
> {
>     # Is $tag an annotated tag? Could/should probably be written using
>     # some plumbing instead of git describe, but with --exact-match,
>     # we avoid the walk-to-the-start-of-history behaviour, so fine for
>     # this demo.
>     git describe --exact-match --match=$tag $tag >/dev/null 2>/dev/null || return 1

Probably "git cat-file -t $tag" is the simplest way to see if it points to a tag.

Show 10 quoted lines
>     # Can it be used to describe HEAD, i.e. is it an ancestor of HEAD?
>     git merge-base --is-ancestor $tag HEAD || return 1
> 
>     # Find the number that "git describe" would append.
>     count=$(git rev-list --count $tag..HEAD)
>     if [ $count -eq 0 ] ; then
>         echo "$tag"
>     else
>         echo "$tag-$count-$head"
>     fi
You can query both of these at once with:
  git rev-list --count --left-right $tag...HEAD

That will traverse down to the merge base and give you two counts. If the first one is 0, then $tag is a direct ancestor. And the second one is the count of what's in HEAD.

At first glance, it seems like you'd waste time counting the HEAD side when the --is-ancestor check could have rejected the tag earlier. But in practice I think the time will always be dominated by walking down to the merge base in all commands.

> I also don't know if either the --is-ancestor or the rev-list count
> could end up doing the same walk-all-commits we're trying to avoid.

It shouldn't. In all of those cases we'll generally walk breadth-first down to the merge base. They're also operations that can take advantage of other optimizations that git-describe never learned about. E.g., generation numbers in the commit graph.

We can even do fast --count with reachability bitmaps, though I wouldn't expect most dev repos to have bitmaps built. Also, it looks like "--left-right --count" does not support bitmaps. IMHO that is a bug. ;)

-Peff
Previous: Rasmus VillemoesNext: Masahiro Yamada
Message 26 of 27 in “Re: [PATCH] setlocalversion: Add workaround for "git describe" performance issue”
  1. Rasmus VillemoesOct 31, 2024
  2. Jeff KingOct 31, 2024
  3. Jeff KingOct 31, 2024
  4. Jeff KingOct 31, 2024
  5. Benno EversNov 4, 2024
  6. 0/4 perf improvements for git-describe with few tagsJeff King, Nov 6, 2024
  7. Jeff KingNov 6, 2024
  8. 1/4 t6120: demonstrate weakness in disjoint-root handlingJeff King, Nov 6, 2024
  9. 2/4 t/perf: add tests for git-describeJeff King, Nov 6, 2024
  10. 3/4 describe: stop digging for max_candidates+1Jeff King, Nov 6, 2024
  11. 4/4 describe: stop traversing when we run out of namesJeff King, Nov 6, 2024
  12. fixup! describe: stop traversing when we run out of namesJosh Steadmon, Dec 4, 2024
  13. Jeff KingDec 4, 2024
  14. Jeff KingDec 4, 2024
  15. describe: drop early return for max_candidates == 0Jeff King, Dec 5, 2024
  16. Josh SteadmonDec 5, 2024
  17. Jeff KingDec 5, 2024
  18. Junio C HamanoDec 6, 2024
  19. Jeff KingDec 6, 2024
  20. Junio C HamanoDec 6, 2024
  21. describe: split "found all tags" and max_candidates logicJeff King, Dec 6, 2024
  22. Junio C HamanoNov 26, 2024
  23. Josh SteadmonDec 4, 2024
  24. Jeff KingDec 4, 2024
  25. Rasmus VillemoesNov 1, 2024
  26. Jeff KingNov 1, 2024
  27. Masahiro YamadaOct 31, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.