16

I'm trying to gather effective ways that others have solved the following problem. At work we've been forced to release a software patch (to be installed on end-user systems) that we only want visible to a specific customer. The custom code is in its own source-control branch. The problem is we have two parallel code lines (and build scripts) to keep in sync, and every time we patch the original code we have to patch and test the customer-specific code.

I'm curious, how do other organizations handle this scenario? We're open to business solutions and not just technical (source-control related) ones. For example, we've talked about telling the customer they can't receive updates on that branch.

Our branching strategy is like this (based on the Visual Studio TFS Branching Guide, although we're using Subversion for it) enter image description here

Dipan Mehta
  • 10,612
Vimes
  • 263

5 Answers5

5

It seems to me the key is "visible"--what about not having a separate code branch at all, but rather a configuration option that changes the behavior?

5

When you start giving out customer specific patches you have immediately created a new version of your product that must be maintained along side of it. That means changes have to be propagated between the two versions. Usually customer specific patches are customizations that should be owned by the customer, including the source code.

It seems unlikely that a patch to fix something would not make it into the mainline branch unless this is a less than optimal temporary fix for an immediate problem. If that is the case then the patch will only need to be maintained until the expected fix makes it into the mainline.

3

Do you see this as a short term or long term thing? The fact is the business has already decided to accommodate this customer so short term it already IS a business decision to be primarily solved by business practices (accepting the extra cost/charging the customer for the cost).

If long term then you will probably see savings if you re-factor the software to easily accommodate that customers needs through configuration (or setup etc).

If it is relatively short term meaning you will soon merge those changes back into the main/development branch and all users will also see the changes then it will probably be acceptable to work within the limitations of your current situation. Like I said the decision of what to do should have been made when the decision to accommodate the customer was made.

Long story short. Long term fix it technically, Short term deal with it.

Of course there is a point where it is a coin toss. If you are at that point then I would do whatever the developers prefer.

3

We use subversion as well - and we come across exact such scenario.

Here are some key points to remember:

  1. While it is necessary one must avoid specific branches for customers the need must be minimized as possible; always ask whether it is possible to generalize the solution that might just work for all.

  2. Customer specific branches must originate from a new release. Suppose you have a version 1.2 and than you have derived from version 1.2.1 till 1.2.11 - the customer branches should be allowed all patches hence customer branch must remain compatible with respect to main version.

  3. Customer specific branch needs to be created a fresh when you start out a new non-compatible version. The unfortunate part is that somehow you might require to re-do the work. One solution can be to create all patches from customer branches needs to be extracted and whatever happens to be still compatible can be applied to new customer branch.

  4. Always, in no circumstances, should you push customer specific changes back to release branch or trunk. However, ideally one should try to generalize the work in such a way that such customer specific work is kept reduced.

I have tried to put these idea together to show in diagram below:

Dipan Mehta
  • 10,612
2

How about introducing an extension mechanism into your code?

Your main code has:

class Foo
{
}

When the program launches it checks for DLL/moral equivalent, in its startup folder for local customizations. If it finds one, it loads and it might contain company specific version of Foo

class FooForABC : Foo
{
}

FooForABC implements the same behavior as Foo but overrides functions as necessary to provide the specific behavior that ABC needs. The technique should be flexible enough to handle any scenario you need to support.

Winston Ewert
  • 25,052