On Thu, 7 May 2020 at 21:42, Jeff King <peff@xxxxxxxx> 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