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