Today I had to read about git tags in order to be able to explain in a better way why somebody would use tags and for what. The old (and still good) git workflow explains very well how to develop using branches but doesn’t explain too well why we create the tags and how should be used on production. It just saying “that commit on master must be tagged for easy future reference to this historical version”. If you followed that guide and now you are ready to go live with your code changes, you maybe wonder what should you do with the tag? Why did you create it. Some people would say, just leave it there, maybe somebody, in a shiny day will take a look to it. Just go to production and do git pull origin master. But I don’t think this is the purpose of the tag.
In my opinion, after you (or an automated process) created the tag, this should be used on the production servers for deployment. So, in production, in the project folder:
We fetch all the git changes:
git fetch --all Fetching origin ... bf53087..f69423b master -> origin/master * [new tag] 1.1 -> 1.1
As you can see, we have some changes in master branch and a the new created tag.
Now I will do:
git checkout 1.1
And I will see a message like this:
Note: checking out '1.1'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b new_branch_name HEAD is now at f69423b... fix a bug; new feature
The text above explain us that we are in a detached HEAD. That means we are no longer on a branch, but we have checked out a specific commit in the history (the one with the hash f69423b…). Also, a tag is represents an immutable content, used only to access it with the guarantee to get the same content every time. So, any changes you do in the tag (if you have the funny idea to do changes on production) will be lost at the next checkout.
Now, your production project is in version 1.1.
Why the tagging is good:
1. No conflict in case somebody changes the production files (the changes will be overwritten).
If you try to checkout a new tag, eg: git checkout 1.2
and you have local changes, you will get a messages like:
error: Your local changes to the following files would be overwritten by checkout: file2 Please, commit your changes or stash them before you can switch branches. Aborting
Anyway, keep in mind to not commit from the tag because your changes will still be lost when you do: git checkout 1.2. In order to save the changes, you should create a branch from the tag, commit the changes into branch, merge the branch into master and tag the master.
2. Easy rollback!
If it is something wrong with the version 1.1, don’t wait until the bug is fixed, tested, tagged and so on… Just do on production: git checkout 1.0
and you are back into the previous version. (it takes less than 5 seconds).
3. Easy for QA and managers to know what version is on production (you can create even tools to show the version online with a nice number like 1.1, not “Dear manager, we deployed the version 604a8d2fc3223ea28d752c8d9fc8d1b05ed543dc…”)
4. Very easy when you have to search for changes long back into time or to compare two releases like 2.12 and 1.1.
And probably more, but they don’t come into my mind right now.