Additionally, this system dies horribly once you introduce branching.
Versioning is another problem I want to introduce to the Test Case Wiki. The test case wiki is an idea I've had for a public wiki for hairy problems with numerous, poor implementations. I.e. a page on implementing a library for handling times and dates. "Have you thought of the following corner cases?". Software Versioning belongs there too.
One way to deal with this is by renaming the artifact itself. So for a project foo-1.0.0 with a branch for Initech, instead of trying to figure out how to increment the version, you make foo-initech-1.0.0, and start incrementing its versions independently until you can get back in sync. This seems to work well as long as foo-initech doesn't itself start getting used as a dependency by anyone other than Initech.
At the day job, we commonly see situations where the customer has a bug they need fixed, and they're not willing to wait for the next scheduled release. We give them a one-off release containing only that fix. What do you label it? If you label it 1.0.1, then the next "official" release will be 1.0.2. Worse, what is the label for another release off the branch, after your trunk release of 1.0.2? I find this unsatisfactory because the two releases are not necessarily related to each other. AFAICT, all version systems that involve only numbers and dots will either fail to handle branches, or become horrifically complex.
I've seen products where releases were branches off branches. This happened because the customer is extremely risk adverse and we had new code in trunk that they didn't want to test; they wanted known-good code plus a subset of trunk. Management went along with it because the customer is several orders of magnitude larger. We strayed from trunk for so long that trunk got dropped, and one of the branches was designated the new trunk.
My general goals for a version system are:
1) provide a unique version for every build
2) Give an indication of where this code came from.
I currently advocate a Git-like solution. I don't promise that this is 100% free of corner cases, but I believe it's better than everything else I've seen. Give every build a SHA1 / GUID. If you're running Git, this is just the SHA1 of the tree, when you build. That is the build's "official version". If you want to see where the build came from, git can draw you a pretty picture. When doing the build, allow the user to specify a human-friendly label, as a string. This can be anything, from "v1.0.1" to "v1.0.0 + one-off fix for MegaCorp" or "Bob's developer build for testing foo". In the product, display both versions.
Interesting. Can you explain why you're doing one-off fixes instead of creating a general release with the fix that everyone can use? This seems like a bit of a complicated edge case that most people don't need a solution for. Semantic Versioning is very simple and has no intention of solving every possible versioning problem.
I never thought it (one-off fixes and branching) was a good idea. It happened because one customer constitutes a large percentage of our revenue, and the business guys made the decision with little care about the effects it would have on the software.
Yes, this is all a complicated edge case, but in certain contexts (corporate software, where you aren't calling the shots, or, you are calling the shots but aren't willing to tell a customer constituting 40% of your revenue to fuck off), you need a better solution. Additionally, at the start of the project you don't always know whether you'll need to support branching. Often, once you figure out you need branching it's too late to fix. Fixing requires changing the build process, testing time, educating QA and Support about the new process, etc.
I'd rather have a well-understood, general purpose solution ahead of time. IMO, "git versioning" accomplishes this, and it's just as simple.
Consider the other side. (These are all things that happened before I arrived.)
Vendor comes in and says, "yes, our software can do it." Then, everyone finds out that it can't. In comes some expensive customization that doesn't quite work right, but everyone has figured out how to work around it well enough. The company is using the database behind the scenes to provide the functionality we need. As such, it's massive heartache to even think about 5 years of upgrades.
However, a fatal error comes up that can't be worked around because of the custom work done by the vendor at implementation time. We need a patch to the executable. However, the idea of just moving up to the new version has everyone here in a cold sweat. Our peers tell us the product has gotten worse than better. It's a 9 month implementation effort, with new training, new workarounds for the bugs, new everything.
You still have the code. You're telling me a simple patch is unfeasible?
This is a very common problem in consultingware. I've seen variations on the theme from both sides of the fence.
Additionally, this system dies horribly once you introduce branching.
Versioning is another problem I want to introduce to the Test Case Wiki. The test case wiki is an idea I've had for a public wiki for hairy problems with numerous, poor implementations. I.e. a page on implementing a library for handling times and dates. "Have you thought of the following corner cases?". Software Versioning belongs there too.