Home > Software design >  Get git tags created over the last year
Get git tags created over the last year

Time:12-18

I want to create a 2022 wrapped for our engineering teams. For that I need the count of releases (=git tags) for every repository from the last year.

However, I couldn't find out how to do this using the command line.

The solution probably would include some variation of

git log --since=1.year.ago --oneline

After walking through @torek's great explanation I ended up with this:

git log --since=1.year.ago --tags --no-walk --oneline | wc -l

CodePudding user response:

There are two "kinds" of tags in Git:

  • annotated tags carry extra information, including the date when the tag itself was created;
  • lightweight tags carry no extra information.

All tags identify some Git object, usually a commit, and each commit has two date-and-time stamps attached. Be careful that when using an annotated tag, you consider the tag's date, rather than one of the two commit dates. Since lightweight tags have no tagger date, you must choose what to do with them: ignore them entirely, or perhaps pretend that the tagger date is one of the two commit date stamps.

If you have no lightweight tags, this complication goes away.

The git tag and git for-each-ref commands are the main two commands for inspecting tags directly. Both will let you sort the tags by whatever sorting key you like; using --sort=taggerdate (oldest first) or --sort=-taggerdate (newest first) is likely what you want here.

You may, however, not be looking for the tagger date in the first place. Suppose commit a123456 was created on 29 Dec 2021, and then tag v3.1415 was created on 3 Jan 2022. Does this count as a release from 2022, or from 2021? You'll need to decide how to handle the fact that an annotated tag's date is separate from the two dates in the commit it tags (assuming it tags a commit in the first place).

So, your first task is to decide how to handle all these fiddly details. Then you can pick one of the --sort options or use a modified version of Lazy Badger's suggestion: add --no-walk to the git log command and you'll get just the tagged commits, sorted by committer date (by default, though you can sort by author date if you wish). Note that Git will not use the tagger date here.

If you choose to go with git for-each-ref refs/tags—which will be the most robust solution once you handle all the fiddly details—you'll probably want to:

  • list out the tag names, selected dates, and target object hash IDs;
  • check whether the tag itself is annotated, if necessary, and that the target object is a commit;
  • if sorting with -taggerdate or -authordate or -committerdate (depending on the decision you made here), discard the remaining tags as soon as you get one that's "too old"

and now you have the list of tags and all auxiliary information needed. This is just a small matter of script programming, using for-each-ref's formatting directives and some simple shell (sh/bash) script for instance. It's probably possible to use the fancy %(if) directives, but I find that they are very messy to use compared to writing a bit of shell code.

  • Related