Team Foundation Server: Changesets and Hotfixes
Woo hoo I'm just full of questions today.
At work we use TFS-- with the loosest possible definition of "use". We check in and out, and back it up, and that's about it. There's pretty much zero institutional knowledge about version control or change management. I'm trying to change that, but want to make sure I Do It Right (Enough) with the tools I have.
So here's the pickle:
- We have a "base" version of the product we sell. All the standard business logic, functionality, etc.
- When we sell it, we take a compiled version of the "base" version, and add the dlls to a custom product which is then customized.
There's sometimes bugs in the "base" version, and the only way to fix them is to implement the hotfix in "base", compile the dll, and move the dll to the "custom" layer. Which sounds good and fine except:
- It introduces new features that aren't implemented in the custom layer
- It may cause regression based on OTHER changes in the base version
- It may actually break things, if tightly-coupled interfaces have changed between the base and the custom layer (I know they shouldn't-- whole other oildrum of monkeys there)
So here we are with TFS. Let's say I know the changeset that the "base" version of this particular custom version was built against. Widget Corp is using base changeset 234, so they have product version 8.0.234. Okay.
But the base product is now up to 8.2.557.
We find a bug, and implement a hotfix for it, which requires modifying the base product. I go into TFS, find changeset 234 and... now what?
I don't want (or can't) upgrade Widget Corp to .557. Do I create a fork of 234 specifically for widget corp, and apply the hotfix just to them? Is there any way of writing a generic hotfix "changeset", and sending it off to all forks of the base?
How do I handle hotfixes in this situation?
@Lorne-Kates I don't know TFS, but you'd need to create a branch for that release and back port the fixes there. Then you can build just the version you need.
Obviously, if you have a lot of different branches that need to be supported, that's going to be a headache, but that's not something version control can solve, except to help you keep organized.
If you're lucky, you should be able to merge exactly the bug fix back into your maintenance branches. If not, you'll need to reimplement it. The difference will probably be how old it is and how much has changed, of course.
One method is to create a branch for each version released to a customer, as @boomzilla said.
At my old job, we did something different: We used semver for all base components and created one maintenance branch per major version. Each customer was always kept up-to-date on their major version of all components in their customized package.
To be able handle customer-specific patches, we cloned each components' repository for each customer and made master track the correct version branch (we used Git). If a component had customer-specific patches, you just had to merge the upstream changes into the local branch. No idea whether that's also possible in a centralized VCS like TFS (probably not, since you can't make local commits). If you don't have customer-specific patches anyway or if you can easily isolate them somehow, that's not a problem anyway.
The third approach is to sell a customer an upgrade to the latest version whenever you can offer a major bugfix or whenever they request a fix. We did that whenever backporting a patch to an old version became too painful. Worked most of the time as well.
MSDN have some example scenarios here and how you recommend you use TFS.
However they are variations of what has already been said here.
If I was going about this, I'd have a branch for each major release (so that the main flow of features wouldn't need to be held up utterly because of a release; you'd just decide the cut-off point after which features would have to wait for the next bus) and then a branch for each customer; the customer branches would usually stick to a single major version (the release branch from which they derived) except when the customer agrees to a shift in version.
I'd also try my damnedest to keep changes flowing in a single direction: bugfix/feature branches to main branch to release branch(es) to customer branches. In a pinch, straight from a bugfix/feature branch to a release or customer branch. Going the other way and you're into a mess of cherrypicking (or whatever the TFS name is; same old pain in any case) and that can suck up lots of developer time without delivering much value.