From: Jeff King <peff@peff.net>
To: Rasmus Villemoes <ravi@prevas.dk>
Cc: Josh Poimboeuf <jpoimboe@kernel.org>,
Masahiro Yamada <masahiroy@kernel.org>,
linux-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org,
git@vger.kernel.org
Subject: Re: [PATCH] setlocalversion: Add workaround for "git describe" performance issue
Date: Fri, 1 Nov 2024 07:39:10 -0400 [thread overview]
Message-ID: <20241101113910.GA2301440@coredump.intra.peff.net> (raw)
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.
> ===
> # 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.
> # 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
next prev parent reply other threads:[~2024-11-01 11:39 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-31 1:20 [PATCH] setlocalversion: Add workaround for "git describe" performance issue Josh Poimboeuf
2024-10-31 10:37 ` Rasmus Villemoes
2024-10-31 11:42 ` Jeff King
2024-10-31 12:24 ` Jeff King
2024-10-31 14:43 ` Jeff King
2024-11-04 12:37 ` Benno Evers
2024-11-01 10:23 ` Rasmus Villemoes
2024-11-01 11:39 ` Jeff King [this message]
2024-10-31 11:43 ` Masahiro Yamada
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241101113910.GA2301440@coredump.intra.peff.net \
--to=peff@peff.net \
--cc=git@vger.kernel.org \
--cc=jpoimboe@kernel.org \
--cc=linux-kbuild@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=masahiroy@kernel.org \
--cc=ravi@prevas.dk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox