How to derive application build version string with Git's `describe` command?

amn picture amn · Jul 21, 2010 · Viewed 16.2k times · Source

I want to compose application build version that is automatically derived from the Git branch name I am on (when building) and the number of commits since the branch has diverged. I believe this will be unique for any commit in my Git repository? Branch names are unique, and commits are linked to each other along a branch? If and when I tag a commit, I can also have the version be prefixed with that tag.

In a way git describe does what I want, but it does not include the branch name I am on, and it includes abbreviated commit SHA-1 hash, which I don't think I need as it does not add anything to the entropy of the string and may be redundant (I may be wrong here, so please correct me).

What are my options? And am I thinking in the right direction here at all? I am just a bit tired of appending numbers to versions when I have more important things to deal with with regards to software development.

I never build with a dirty working tree, by the way. I.e. I always commit changes to the repository before building a public release.

Answer

Aristotle Pagaltzis picture Aristotle Pagaltzis · Jul 21, 2010

The thing you have you to understand about git is that branches are essentially merely commit bookmarks. The fact that you were on the foo branch when you made the 0deadbeef commit is immaterial to the commit itself; the branch is not part of its identity.

(Mercurial bakes the branch name into the commit. In a variety of ways, this is inferior, as Dustin Sallings explains.)

Even assuming that git describe would just use the currently checked out branch – if you have a mergy history, there could be multiple paths leading to the same most recent tagged commit that git describe would use. So there isn’t even necessarily any one branch.

Another note: you may object that even if “3rd commit from tag X” is ambiguous in the general case, git describe could just look at the graph and figure out whether it is ambiguous and if not, leave out the hash. However, there is nothing stopping anyone starting a branch on top of that tag at a later time – so then your describe string would become ambiguous retrospectively.

Bottom line is that the only unambiguous identifier of a commit is its hash. So that must be in there. What git describe does is add some redundant (and in case of the commit number, ambiguous) information that makes the description more useful to the kind of spatial/relational comprehension that humans orient themselves with, within the confines of the Git model.