Version Naming
I wanted to write a very brief note on the version naming scheme I tend to use and why I like it. But it turned into this rather long piece. Sorry ...
Some version names carry a great deal of baggage. Version 1.0 springs to mind as a version name that causes enormous angst. It seems to be held in reserve for use when the particular lump of software is first "ready" or "complete" or something of that ilk. Some projects have decided to avoid 1.0 completely and always have version numbers less than one.
Dave Thomas of Smalltalk and Envy fame once gave a talk about the version numbering scheme used at OTI, and I have used it ever since - whenever I get to choose version names. It's a simple technique that calls for the numbering of goals and steps towards those goals separately. A version name in this scheme looks like "g iii" where g is the number or name of the goal (or intent) and iii is a simple integer increment which indicates the committed (from a version control point of view) step (or attempt) towards attaining the goal.
I tend to just use integers as the goal names, so the first goal name I use for a project is 1. The first increment would be 001 (I use the leading zeros because it appeals to me - and tends to sort better with some tools). So, the very first version name on a new project will most likely be simply 1 001 (the first attempt to get to the first delivery goal). It requires no thought or agonising about the meaning of the numbers, it's just the first go at making the first deliverable.
Delivery of a system will either be time-boxed or functionality-boxed, i.e. it's got to go out on such and such a date, or it must have this list of features. Who can say how many attempts it will take to build a system in these different situations? Not I, and I don't care. It'll take what it takes. When the system is ready, by whatever criteria, I'll release it and note that it was attempt iii that was the first release of the system. For example, 1 132 would not be an untypical number for a substantial system built over several months. If that delivered system needs fixing then it's just a further attempt at the same thing, so perhaps a fixed version would have the name 1 138 if the fix itself took a few attempts.
Deciding that there is a new goal is art. The question will be: is this work we are about to do merely fixing or slightly enhancing the existing system as delivered or is this a new goal that deserves a new major number? I mostly work on database systems and tend to follow the rule of thumb that a major version corresponds to a schema (or object model) shape, and that a schema change implies a major version increment. But that's just me, and even then things are rarely satisfyingly back and white - so it's still art, as is deciding on the name/number for a new goal.
On top of all of the above we have the idea of a branch in project work. This may occur because work starts on version n+1 before version n is ready, or because version n-1 needs a fix. In many version naming schemes one can see astonishingly long version names made up of integers letters and dots all trying to convey where the version fits in to the history. In the above "g iii" scheme, every g is a branch. So, if we release version 1 032 as above and move on to 2 001 and then find a problem with the g=1 system, we just move on to 1 033 etc. If we need to start working on g=3 while g=2 is just being rolled out and g=1 is still in production, still no problem everything is clear. We might have 1 056, 2 021 and 3 002 all being worked on at the same time with the objectives and intent of each branch being clear.
Then we have composition. Projects are not single monolithic blobs, not even small projects. I'll use VisualWorks Store terminology here, which is pretty straight forward - At the top of the grouping pile we find Bundles. For every project I deliver I have a single bundle that contains all the bits that make up the system. Bundles can contain other bundles (for big projects layers help) and Packages. Packages contain code, for example a class definition or a method. So, we have a tree with a single bundle at the root and bits of code at the leaves.
As I work I version the things I'm working on (i.e. I make an immutable copy and assign a version name to that copy - my version crontrol system does most of this work for me). If I'm the team leader of a project I version the top bundle containing a version of the entire system. I do this often and I use SUnit to check the state of each new version, beating people if things have regressed.
Everyone in the team knows the goal so we all agree on a "g" number. I don't care about the increment numbers for any of the bits, other than that they must be sequential (i.e. always going up. I don't mind gaps) - the version control system remembers which versions of what go to make up the whole tree. So, for example, the root of the tree might be at 1 012 but a particularly tricky class might be at 1 046. No worries.
I don't force new version names upon things that have not changed. If I'm working on version g=2 of the system, I'd expect to start off with most components having version numbers like 1 iii. In the future if I find I'm working on version g=42 (the ultimate version of the system, of course) and I find a component with a version number of 1 046, that just shows that the original work was good (well, after ~46 increments it was).
Of course, sometimes we do need to have spontaneous branches. For example, if I find myself fixing a system in the wee small hours, I'm not going to hold back on making a fix and I don't want to worry about any version naming stuff. In these cases, I just append my initials and another increment to the version name. This is saying: This is a fix done by someone other than the agreed maintainer of this code and it's my nnnth attempt, so for example I might have 1 046.bb05 (it took me 5 goes to get it right in this case). As soon as possible I try to have the agreed maintainer of the code adopt (or reject) the changes and merge them in with the body of work for all the "g"'s affected.
Lastly, while some may worry that version numbers get big and even coin phrases like "version number inflation", I don't mind if the g or iii version numbers gets big. Why should it matter? It's just a counter of the number of goals and increments I've worked through.
... and this was a tad longer than I planned. All I wanted to say was I use the Dave Thomas version naming scheme that looks like "g iii" and it works really well for me. There you go.
Comments
The problem I have with this...
[Travis Griggs] December 13, 2006 1:38:42.184
Is that it doesn't scale across multi person projects well. The OpenSource kind in particular. At best what you're attempting to do is provide an insight into what the publish comment had better say. Something like "this is just a little change" vs. "i rewrote quite a bit here." But that's so arbitrary. One man's big change is another man's little change. If it's your project then you have the liberty of making the artistic call when to start a new "goal." But your artistic feel good point to do that is different from someone who uses the same approach. So in the end, I just end up ignoring these things, because it's something that is only meaningful to the author, and I've learned over the years that I am no good at guessing the intent of when to "start a new goal." And then there's the fact that when you get into a multi person open source project, no one can decide when to role the version number, so no one does, and we end up with 1.4666. Or better, 1.52.0.18.92.34. I use the Microsoft versioning model: "build 1387". :)
Scales nicely, I find
[Bruce Badger] December 13, 2006 8:14:50.436
Travis, Dave Thomas' version numbering scheme has scaled quite nicely in my experience. It's essentially what you said you liked (a counter, much like a build number is a counter) while recognising that most projects need to make discrete releases which people can use. Dave's scheme adds no meaning to the increment numbers, so commit comments are most certainly important in order to understand what was fixed in an increment.
Actually don't think "build number" is a scalable idea as a generic version naming scheme - it's usually a term used to identify a build (remarkably enough), i.e. the process of bringing all the bits of a system together. I don't think is says anything about the version history of the bits, it's just a step number at the highest level. Dave's scheme works nicely at all levels of granularity, not just at the root of the tree.
I agree that the art of deciding when there is a new "release" or whatever is a pain. I think it's one of those things that must be left in the hands of an individual, though hopefully an individual that tries for a consensus.
OTI Version Name Schema
[Maximiliano Contieri] December 14, 2006 10:24:13.126
Nice Post !
We also have a version schema based on major and minor versions. Therefore we name applications and classes according to tree branches.
We have several integrity tests (built on SUnit) which enforce our standars.
Every application released in a baseline must have at most two version numbers. what´s more we can easily notice that a particular version belongs (o belonged) to a baseline