Jump to content

Is there a good workflow for concurrent, long-term branches?


Wolfram

Recommended Posts

Hiho.

I get the concept of "Branch per Task", and I think it is great!

However, sometimes (=probably the original idea of using branches) you really need different, maintained versions of your software (for example, internal version, individualized versions for customer A, B, etc.). So the obvious choice is, to create branches for each of these variants. In such a scenario,

- all branches are continuously being worked on and "never end", and especially can contain content that you DO NOT want to merge into the mainline, ever

- however, individual things like new features and bugfixes need to be kept up-to-date for all, by merging/cherrypicking to/from the mainline

- certain features not relevant/allowed for customer X are actively deleted from "his" branch

 

But how can you keep these concurrent branches consistent? If I understand correctly, you effectively can no longer do regular merges (which are always "full" merges of an entire branch), as these will always try to consolidate all differences (and as such, will for example try to delete the above changes for customer X in all other branches as well).

I have experimented now quite a bit with ignores, cloaks, cherrypicks, sutractive merges etc, but I can't seem to find a viable workflow to maintain these branches with manageable effort.

Could you tell me what my options are, and what the best way to deal with this scenario is?

Thanks!

Link to comment
Share on other sites

Hi Wolfram,

I've seen this idea being kicked around before - branching for the sake of maintaining multiple 'kinds' of a product, as opposed to parallel development streams of the *same* product.

The latter has a notion of merging changes back together at some point - be they hotfixes on a release branch going back to the development mainline, or a new feature off a feature branch. The idea is that the product may at various times bifurcate into more than one parallel version, but this is a variation on simply having one line of development. Ultimately it's still just one product. You might get abandoned experimental branches and POCs too, but they don't get merged back.

What you want, I think, is a set of never-ending branches that represent similar products that share code in common, but should not be regarded (and not sold) as one thing. As I'm sure you already know, you can start with a common main branch, make product line-specific branches off that and then have a rule that merges must flow from the main up to the branches, but never the other way (otherwise you'll end up creating a fused product).

This takes some discipline, and if you detect bugs on a specific product (which will be the case for those reported in the field), then you'll have to make the effort to triage those bugs into those that are product line-specific, and those that are common. The product line-specific ones get fixed on the branches, and the common ones get fixed on main (or on temporary topic branches that flyout from main) and then get merged up into all the product line branches. Of course, this doesn't always work out in the heat of development, in which case you have to cherry-pick a fix from the product-line branch back to main, massage it to make sure that no fusion of product line-specific stuff occurs in the merge. It's achievable in Plastic if you isolate your bug reproduction tests and fixes in either single commits or topic branches that flyout off the product line-specific branches - you can cherry pick these without bringing in too much unrelated cruft.

I really would stick to just that flow and avoid cloaks and subtractive merges - these things have their place, but you'd have to be very careful about code organisation, for example, if you want to use cloaking to make a merge back from a product specific branch back to main safe. Which brings me to...

 

Have you considered factoring your codebase into a common piece and stuff that can be product-specific? I would hope that most of your code could be hived off into a library that has just one delivery branch (I'm ignoring release branches, you get the picture, I'm sure) in its own repository. The product specific stuff can then become completely independent projects with their own repositories. You can either go the route of delivering the library as a binary internally, or use an XLink to mount it within your individual projects. You can do both if you want - you'll know when you'll need to do that.

You could go the route of keeping your product lines as one repository with line-specific branches here too; in which case I'd hope that having the common library would cut down on the ceremony of maintaining the branches and sticking to the merge discipline - less code to worry about.

If you go down that last variation, consider using feature toggles and configuration so that the product specific-lines only vary in configuration files and not in main code - in which case you can start to think about cloaking again; this time it might be easier.

So to summarise, it can be done but there is no silver bullet I know of. B)

I'm curious myself now to know if anyone else has experience with this...

Regards,

Gerard

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...