Tag: version

How to: Use tagging in Git (Part VII)

How to: Use tagging in Git (Part VII)

Tagging is a great feature of Git and most other VCSs for that matter, that allows you to hmmm… tag (a warm round of applause for Captain Obvious) specific points in history as being important.

And this is the exact context in which Semantic Versioning starts to make more sense than ever. Following the wisdom within these two posts will at least make you look serious about software development, releasing new versions and fancy patches and stuff…

Listing Your Tags

Running the tag command with no options or arguments will list all the available tags in your repository:

git tag

But you can also list only the tags with a particular pattern. The Git source repo, for instance, contains more than 240 tags. If you’re only interested in looking at the 1.4.2 series, you can run this:

$ git tag -l 'v1.4.2.*'
v1.4.2.1
v1.4.2.2
v1.4.2.3
v1.4.2.4

Creating New Tags

We can have two different types of tags: lightweight and annotated. I’m not going to go on about the differences between those two, or why one of them is better than the other, they are both acting like pointers to a specific commit, but I prefer annotated tags as they can store additional information and be signed and verified with GNU Privacy Guard (GPG) – which you can probably read more about in the man page or the official docs.

To create an annotated tag, just use the -a option with the git tag command like this:

git tag -a v1.0.0 -m 'Version 1.0.0'

Tagging

The -m option specifies the tagging message which is stored within the tag object, but if you don’t specify it, Git will launch your editor so you can type it in.

Note to self: I’m planning on writing some script at some point that would help me automate the creation of change logs for major and minor versions, based on the commit messages between versions or todo list entries.

Also if, say you forgot to tag an important commit sometime earlier, you can still do it now by referencing its checksum:

git tag -a <tagname>. -m '<message>' <checksum>

Update: One more thing, in case you made a horrible typo on the tag you just created (like I just shamefully did), there’s something you can do that works pretty much like the --amend option for git commit:

git tag <tag-name> <tag-name> -f -m "<new-message>"

That will create a new tag with the same name by overwriting the original, or you could pop up your editor to type in more complex messages by running:

git tag <tag-name> <tag-name> -f -a

Viewing Tags

Viewing detailed information about individual tags, to be more precise, can be done using the git show command followed by the tag’s name:

git show v1.0.0

Again, this command has tons of useful options but you’re gonna try them all out on your own. I’m now giving you some more interesting combos that might come in handy:

git tag -l v1* -n999

That one will display the first maximum of 999 lines of all the tags starting with v1 – feel free to filter these as you like and display more or less lines of the tag message.

git log --oneline --decorate --reverse v1.0.0 v2.0.0

Use the one above to display a list of all the commits between major versions v1 and v2 in reverse order.

git log --oneline --decorate --graph --reverse --all

Or list the entire repository history in the same format as the above while also displaying branch graphs.

Sharing Tags

For some reason, git push doesn’t transfer tags too by default, so it needs to be done separately. You can either do it one tag at a time:

git push origin <tagname>

or by using the --tags option for all tags at once (it will only transfer tags that are not already on the remote anyway):

git push origin --tags

After this, any clone or pull operation will fetch all the tags as well so you can just go and take a long nice poop because:

  • you deserve it
  • your repo looks legit
  • according to semver, it now also has a meaning

What is Semantic Versioning and Why Care?

In the world of software management there exists a dread place called “dependency hell.” The bigger your system grows and the more packages you integrate into your software, the more likely you are to find yourself, one day, in this pit of despair.

What is this?

If you aren’t already using Semantic Versioning, you should. It makes it much easier to figure out how to version your releases. Even if you’re ‘just’ building software for your internal organization, or a single customer, you should still care about versioning of the software you release. Instead of an ad-hoc versioning scheme, Semantic Versioning offers a set of easy-to-understand rules about when to increment which version number.

Semantic Versioning

Basically, you:

  • increment the patch version (e.g. from 2.3.4 to 2.3.5) when you only release bug fixes
  • increment the minor version (e.g. from 1.3.2 to 1.4.0) when you add new features
  • increment the major version (e.g. from 3.2.9 to 4.0.0) when you introduce breaking changes

Why should I care?

This makes it much easier for you when you need to make a decision on a new version number, and it also makes it much easier for consumers of your software to understand when an update is ‘safe’, and when they should set aside some time to test compatibility.

If all of this sounds desirable, all you need to do to start using Semantic Versioning is to declare that you are doing so and then follow the rules. Link to this website from your README so others know the rules and can benefit from them.

This is somewhat of a rip-off of Mark Seemann’s post on Semantic Versioning with Continuous Deployment, which somewhat of a lesser rip-off of the original page on Semantic Versioning, created by Tom Preston-Werner, co-founder of Github and also the guy who made Gravatars.

OK, I want in.

All of that being said, check out the official page at semver.org for detailed specifications, examples and a very useful F.A.Q. section. I think this is a great starting point for when we dive into How to: Use tagging in Git (Part VII).