All of lore.kernel.org
 help / color / mirror / Atom feed
* tags sorted by their depth, *committerdate, and taggerdate
@ 2020-05-06 18:16 clime
  2020-05-07 19:42 ` Jeff King
  0 siblings, 1 reply; 4+ messages in thread
From: clime @ 2020-05-06 18:16 UTC (permalink / raw)
  To: Git List

Hello,

I have some very specific requirements to get annotated tags sorted in
a certain way. I would like them to be sorted:
- primarily by their depth (i.e. how far they are from current HEAD
and if they are not reachable then they should not be displayed).
- secondarily by committerdate of the commit they are associated with
- ternarily by taggerdate

Is something like that possible?
Is something like that possible even with git 1.7.1?

If this isn't possible, I am thinking I could write some simple
utility in C to do it but can I rely on certain binary format of
commit and tag objects? Has the format changed at some point since git
1.7.1? Is there a git library I could use for it? Or is the format
documented somewhere?

Thank you very much and sorry for so many questions
clime

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: tags sorted by their depth, *committerdate, and taggerdate
  2020-05-06 18:16 tags sorted by their depth, *committerdate, and taggerdate clime
@ 2020-05-07 19:42 ` Jeff King
  2020-05-07 19:47   ` clime
  2020-05-07 23:56   ` brian m. carlson
  0 siblings, 2 replies; 4+ messages in thread
From: Jeff King @ 2020-05-07 19:42 UTC (permalink / raw)
  To: clime; +Cc: Git List

On Wed, May 06, 2020 at 08:16:35PM +0200, clime wrote:

> I have some very specific requirements to get annotated tags sorted in
> a certain way. I would like them to be sorted:
> - primarily by their depth (i.e. how far they are from current HEAD
> and if they are not reachable then they should not be displayed).
> - secondarily by committerdate of the commit they are associated with
> - ternarily by taggerdate

There's no way to compute the depth with for-each-ref or similar. In
fact, I'm not even sure of a way to do it for all tags with a single
command. So I'd probably script something like:

  git for-each-ref \
    --format='%(*committerdate:unix) %(taggerdate:unix) %(refname)' \
    refs/tags |
  while read cdate tdate ref; do
    depth=$(git rev-list --count --ancestry-path $ref..HEAD)

    # if depth is 0, then either $ref isn't an ancestor of HEAD, or $ref
    # points to the same commit as HEAD. Not sure if you want to salvage
    # the latter case, but you could compare rev-parse output on the
    # two.
    if test "$depth" = 0; then
      continue
    fi

    echo "$depth $cdate $tdate $ref"
  done |
  sort -k 3rn -k 2rn -k 1n

But it's kind of expensive (we'd walk over the history near HEAD
multiple times, once per tag).

It seems like git-describe should be able to do a better job of the
traversal, but I had trouble convincing it to do so.

> Is something like that possible?
> Is something like that possible even with git 1.7.1?

You'd need v1.7.2 for --ancestry-path. You could just use "$ref..HEAD"
without it, and instead do:

  git merge-base --is-ancestor $ref HEAD

to cover the case where they aren't reachable from HEAD. But of course
that's an extra traversal per tag.

I'm not sure why you need to use such an antique version of Git.

> If this isn't possible, I am thinking I could write some simple
> utility in C to do it but can I rely on certain binary format of
> commit and tag objects? Has the format changed at some point since git
> 1.7.1? Is there a git library I could use for it? Or is the format
> documented somewhere?

Doing better would require a custom traversal of the commits. You could
look something with libgit2 (which is in C, but has bindings to some
other languages).

-Peff

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: tags sorted by their depth, *committerdate, and taggerdate
  2020-05-07 19:42 ` Jeff King
@ 2020-05-07 19:47   ` clime
  2020-05-07 23:56   ` brian m. carlson
  1 sibling, 0 replies; 4+ messages in thread
From: clime @ 2020-05-07 19:47 UTC (permalink / raw)
  To: Jeff King; +Cc: Git List

On Thu, 7 May 2020 at 21:42, Jeff King <peff@peff.net> wrote:
>
> On Wed, May 06, 2020 at 08:16:35PM +0200, clime wrote:
>
> > I have some very specific requirements to get annotated tags sorted in
> > a certain way. I would like them to be sorted:
> > - primarily by their depth (i.e. how far they are from current HEAD
> > and if they are not reachable then they should not be displayed).
> > - secondarily by committerdate of the commit they are associated with
> > - ternarily by taggerdate
>
> There's no way to compute the depth with for-each-ref or similar. In
> fact, I'm not even sure of a way to do it for all tags with a single
> command. So I'd probably script something like:
>
>   git for-each-ref \
>     --format='%(*committerdate:unix) %(taggerdate:unix) %(refname)' \
>     refs/tags |
>   while read cdate tdate ref; do
>     depth=$(git rev-list --count --ancestry-path $ref..HEAD)
>
>     # if depth is 0, then either $ref isn't an ancestor of HEAD, or $ref
>     # points to the same commit as HEAD. Not sure if you want to salvage
>     # the latter case, but you could compare rev-parse output on the
>     # two.
>     if test "$depth" = 0; then
>       continue
>     fi
>
>     echo "$depth $cdate $tdate $ref"
>   done |
>   sort -k 3rn -k 2rn -k 1n
>
> But it's kind of expensive (we'd walk over the history near HEAD
> multiple times, once per tag).
>
> It seems like git-describe should be able to do a better job of the
> traversal, but I had trouble convincing it to do so.
>
> > Is something like that possible?
> > Is something like that possible even with git 1.7.1?
>
> You'd need v1.7.2 for --ancestry-path. You could just use "$ref..HEAD"
> without it, and instead do:
>
>   git merge-base --is-ancestor $ref HEAD
>
> to cover the case where they aren't reachable from HEAD. But of course
> that's an extra traversal per tag.
>
> I'm not sure why you need to use such an antique version of Git.
>
> > If this isn't possible, I am thinking I could write some simple
> > utility in C to do it but can I rely on certain binary format of
> > commit and tag objects? Has the format changed at some point since git
> > 1.7.1? Is there a git library I could use for it? Or is the format
> > documented somewhere?
>
> Doing better would require a custom traversal of the commits. You could
> look something with libgit2 (which is in C, but has bindings to some
> other languages).

Thank you, Jeff. I didn't actually expect somebody would respond to my
crazy demand.

I probably could drop support for that version, it is in centos:6 but
that is soon going to be eoled.

Thank you also for the scripts. I would like to be the operation as
fast as possible so I am actually considering libgit2 now.

Thank you very much again for your advice
clime

>
> -Peff

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: tags sorted by their depth, *committerdate, and taggerdate
  2020-05-07 19:42 ` Jeff King
  2020-05-07 19:47   ` clime
@ 2020-05-07 23:56   ` brian m. carlson
  1 sibling, 0 replies; 4+ messages in thread
From: brian m. carlson @ 2020-05-07 23:56 UTC (permalink / raw)
  To: Jeff King; +Cc: clime, Git List

[-- Attachment #1: Type: text/plain, Size: 865 bytes --]

On 2020-05-07 at 19:42:24, Jeff King wrote:
> On Wed, May 06, 2020 at 08:16:35PM +0200, clime wrote:
> > Is something like that possible?
> > Is something like that possible even with git 1.7.1?
> 
> You'd need v1.7.2 for --ancestry-path. You could just use "$ref..HEAD"
> without it, and instead do:
> 
>   git merge-base --is-ancestor $ref HEAD
> 
> to cover the case where they aren't reachable from HEAD. But of course
> that's an extra traversal per tag.

I believe git merge-base --is-ancestor is much newer than v1.7.1.  I
think you have to use the old style, which IIRC is this:

  test "$(git rev-parse "$ref")" = "$(git merge-base "$ref" HEAD)"

If you'd like a more modern version for CentOS 6, I think Software
Collections has one with suitable support.
-- 
brian m. carlson: Houston, Texas, US
OpenPGP: https://keybase.io/bk2204

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 263 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-05-07 23:57 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-06 18:16 tags sorted by their depth, *committerdate, and taggerdate clime
2020-05-07 19:42 ` Jeff King
2020-05-07 19:47   ` clime
2020-05-07 23:56   ` brian m. carlson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.