2

My company currently has SVN as main version control and we are in process of migrating to Git. Doing that is a perfect chance to do a structure reorganization.

Before I get to that let me describe current situation and our use cases. We have one main product and 20-ish clients which have customizations in place. What that means is that if client A wants a module from project customized to his own needs, we would do that.

So currently we have a default version in place which has its own repository. Each client has its own repository separated from the default one. The logic is that a client repository through composer.json shows on specific tagged default version. With some inner logic, overrides take precedence on client projects so that we don't touch the main project when it comes to customizations. SaaS is not a possibility, we need on premise installs.

Although this is the only way I currently see as a model which suits our needs, I find it rather cumbersome to have to maintain 20 repositories instead of one.

Solutions and why they don't work

  1. My initial idea was having a git submodules. This would however be absolutely the same with the current situation as I couldn't unify repositories
  2. Other idea was to have a single repository with Clients folder, and then set Jenkins to grab a specific folder depending on what project is being built. This however fails because clients have strict requirements of when and how the updates will happen and we can't force it on them. This means that if clients have a v1.0, we do have a contract to deliver fixes, but they are not obliged to go to v2.0. So in this configuration, I can no longer target v1.0 if development went forward
  3. Last but not least, I had a plan of having Git flow set up where each branch would be a separate client...thus also having master, dev and feature branches for each client, meaning that one repo would have about 20*3=60 branches minimum. While this is manageable with some strict rules, I have an issue here because if I have 20 clients on v1.0 and one of them notices a bug in version, I need to do a fix on master and then propagate that fix by hand to each branch. Even worse, if default master went on with development and is currently at v2.0, introducing a quickfix would mean cherry picking commits and propagating it to other X branches.

Is there any other solution that would fit my model which I'm not seeing here?

Norgul
  • 149

3 Answers3

3

To me, it's a decision between single repo and repo per client. As you also said, the branch per client idea doesn't seem reasonable to me (too complicated, no advantages).

Now, I've been working with both approaches, and the advantages of a single repo over multiple repos are to me:

  • Ease of development: one checkout gets all the clients, no need to set up 20 workspaces (git submodules could also help)
  • Tags and branches hold all the code: there's only one v1.0. If I understood it correctly, you use the same version number across all clients, so that's an advantage for you.

You had concerns about customers still being on the 1.x branch, while others are already on 2.x. I suggest using branches for this. While your master branch contains the 2.x code, you could still work on the 1.x code on another branch, and start releases from that one.

In one project, we called this "generations". While there was a master, branch generation/1.x was also worked on, and we started bugfix, release or even feature branches from it. You can always cherry pick (SVN: "merge") commits between generations (or master). Finally, if one customer moves on to 2.x, you could move his directory over to master (or whatever generation is appropriate).

To me, the major concern would be scaling (or repo size): if the number of your clients grows, or your codebase takes lots of disk space, a single repo might get hard to handle.

fxnn
  • 144
3

We have one main product and 20-ish clients which have customizations in place

This kind of separation is not one that source control is designed to support. You should have one repo per client.

Rather than have the entire codebase replicated per client you should change your code, splitting it into as many libraries as possible*, each with its own repo. The goal being to maximise the number of libraries that can be shared across all the clients and thus only require a single repo per library

*whilst being sensible about responsibility boundaries and loose coupling

Ewan
  • 83,178
2

I’m going to cut the knot and offer an entirely different solution:

Instead of shipping different code for different clients out of different repositories, I would instead unify all the code, ship versions, and control customizations via configurations, or, where there is no conflict between what customers want, ship one client’s customizations as features or enhancements for other clients.

This is of course in part a business decision, but it is one that might be worth floating if the specifics of your application supports it.