- Posted by Ian Suttle on January 6, 2009
- Filed under Source Control
We’ve been trying to tackle the topic of how to support multiple versions of software safely. The emphasis has been on ensuring the changes you make to software are the only changes reflected in a build. This is different than your changes being included with other changes done you’re not aware of. Shared libraries are the most obvious examples I can think of. Getting in to that situation introduces loads of risk we have no interest in taking on. Alas, that is the situation we’re in today.
Scenario: Library changes and we need to update an older version
In this scenario consider we have a shared library with a bunch of classes in it. That shared library is included in a web app we released. We label the solution as “My App 1.0.0”. Over time the shared library is modified to the point the it loses backwards compatibility for one reason or another. The modified solution is known as “My App 2.0.0”. Suddenly we come across a bug with the “My App 1.0.0” version which requires emergency resolution in the shared library.
We can’t get latest on that library to apply our fix because latest is now “My App 2.0.0”. If we get from the label “My App 1.0.0” we could make our fix and mark it as “My App 1.0.1”. The problem then is checking that code back in would become “latest” where in reality “My App 2.0.0” should continue to be the latest. Of course, we’d want to apply our fix to “My App 2.0.0” if it still applies.
A proposed solution:
1. Get “My App 1.0.0”
2. Apply fix
3. Check in the code and label solution as “My App 1.0.1”
4. Get “My App 2.0.0”
5. Apply fix
6. Check in the code and label solution as “My App 2.0.0”
Another proposed solution:
1. On release, branch "My App 1.0.0" to a Release area of your repository. The branch would include all libraries necessary to support the application.
2. Continue developing "My App 2.0.0" in the trunk
3. To fix something in "My App 1.0.0" update the branch created earlier and apply a label such as "My App 1.0.1"
4. Merge changes from "My App 1.0.1" in to the trunk where "My App 2.0.0" is being developed
Both options provide a fix to “My App 1.0.0” to be tested and released, applies the fix to “My App 2.0.0”, and leaves “My App 2.0.0” as “latest”. If in the future another fix were needed for “My App 1.0.1”, we’d repeat this process.
How would you normally go about this? Are we making it too complicated or does this sound reasonable? Does the fact that we're using Team Foundation Server for our respository offer any advantages or disadvantages?