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,542
  • 2
  • 33
  • 67
Vimes
  • 263
  • 2
  • 8
  • If you were using `hg` or `git` I might suggest that you look at using Patch Queues ([Mercurial Queues Extension](http://mercurial.selenic.com/wiki/MqExtension) or [Stacked Git](http://www.procode.org/stgit/)) but I don't know if TFS has anything similar. – Mark Booth Jan 18 '12 at 18:09
  • Maybe I should have specified, we are using Subversion even though we use a TFS-suggesting branching strategy :P Would Patch Queues cut down on the necessary testing? It looks like these are for source-control patches? We're dealing with patches the customer installs onto end-user systems. – Vimes Jan 18 '12 at 18:28
  • 2
    A business solution would be: Don't do it. – JeffO Jan 18 '12 at 20:52
  • @JeffO good call =) In any case, is there any way you can make this a data driven runtime switch? – Patrick Hughes Jan 18 '12 at 21:17
  • 1
    @JohnB - Sorry, I don't know, but if you have source patches then your build system should be able to automate the tests, plus keeping the *per customer patches* outside of `svn` means they don't clutter up your normal workflow. If Patch Queues look like they might be useful, you could try them out using [git-svn](http://utsl.gen.nz/talks/git-svn/intro.html) or [hgsubversion](http://mercurial.selenic.com/wiki/HgSubversion). Using a DVCS front end to smooth out a tricky workflow in `svn` might even encourage people to consider moving to a DVCS wholesale, to gain all of the other benefits. – Mark Booth Jan 19 '12 at 11:35
  • I like JeffO's response ;) I wish it were possible (we'll see). @MarkBooth, thanks for the links. I didn't know those tools existed, and they look really cool. I'll take a look. – Vimes Jan 20 '12 at 18:43

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?

Loren Pechtel
  • 3,371
  • 24
  • 19
  • This could work for simple customizations, but more complex ones could make the product more awkward and unstable for all customers. – FrustratedWithFormsDesigner Jan 18 '12 at 18:22
  • 3
    @FrustratedWithFormsDesigner Complex customizations for single clients represent gross negligence in product management and design. Any solution that requires a seperate branch for a single customer for a product represents a gross inadequacy in the product to meet all customers needs and poor stewardship on the part of the product owner. – maple_shaft Jan 18 '12 at 19:13
  • ... cont, I have seen this nightmare scenario as a smoking gun in every single one of the most reprehensibly mismanaged companies I have ever had the displeasure to work with. I believe that this is such a red flag, that on interviews I ask now if they have seperate branches for customers in any supported products that are not EOL or nearing EOL. If the answer is anything but 'Absolutely not' then I would NEVER take that job. – maple_shaft Jan 18 '12 at 19:21
  • 2
    I've also seen this bite my previous employer over and over again. It's just bad practice, but usually it's something that management want and won't back down over. Particularly if you're using Subversion, this is just a nightmare that won't go away - keeping the code in sync will hurt, time and time again. – Steve Hill Jan 18 '12 at 19:34
  • 1
    @maple_shaft - But did you think to ask the question "have you ever used code branching to implement internationalization"? – psr Jan 18 '12 at 19:38
  • @psr That argument is moot. A properly well-designed internationalized software application will implement resource bundles for various locales. – maple_shaft Jan 18 '12 at 19:50
  • 3
    @maple_shaft - I was joking, but, actually, that was my point, using branching to handle internationalization is at least as bad as customer specific branches. It's not moot in the sense that you probably don't want to work in such a place either. It is moot in that I was going fairly off topic. – psr Jan 18 '12 at 20:03
  • @psr My apologies, I misinterpreted your comment as defense of seperate branching as an acceptable solution for internationalization of software :) – maple_shaft Jan 18 '12 at 20:06
  • Just as a note: This strategy (which we also use) is commonly called a "feature flag", "feature switch" or "feature toggle". You can use them at run- or at build time. See e.g. this blog post: http://code.flickr.com/blog/2009/12/02/flipping-out/ – sleske Jan 19 '12 at 07:52
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.

Charles Lambert
  • 2,019
  • 17
  • 18
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.

ElGringoGrande
  • 2,913
  • 22
  • 20
2

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,542
  • 2
  • 33
  • 67
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
  • 24,732
  • 12
  • 72
  • 103