We are starting to refactor a mid-sized HMVC web application supporting around 30 clients. Currently, the code is managed by a single branch in an SVN repository. Sometimes, a change is client specific, other times, the change will apply to all clients. We are the only ones dealing with the source.
Each client requires heavy customization, from business logic to display, but all work basically the same, evidenced by the fact that all clients share database tables with specific company information distinguished with a client_id column.
There are two ideas surrounding the organization of the new code and I'm having a hard time wrapping my head around the differences between the approaches and the pros and cons of each. Any help understanding this better would be appreciated.
1) Put each individual piece of application functionality in its own git repository. Create interfaces for all pieces of application functionality to manage the dependencies between these pieces. Manage these application components with Composer, a PHP package manager, so that a client will consist of a package manifest that contains all of its components and the version of that component. If a single application needs a change to a module, create a new package/repository by forking that module. If the change spans multiple modules, create multiple new repositories, publish them as composer packages, and add the new packages to the client manifest.
2) Create a git repository for the application as a whole. Create a fork (or branch) for each client. For client specific changes, use the fork. For a change to all clients, use the main repository and for each client, merge the upstream repository into the client repository as needed.
Which approach will provide long-term manageability and flexibility for the development teams? Is there an alternate approach to consider? As it stands now, it is difficult to make both a client specific change and a systemwide change due to the hierarchical system and years of abuse.
The first approach is similar to a component approach I detailed here.
The difference is that you are using php Composer, which means you mignt not need to rely on git submodule
as I usually suggest, since the Composer FAQ suggests that:
Adding dependencies installed via git to a git repo will show them as submodules.
This is problematic because they are not real submodules, and you will run into issues.
Git submodules might still be needed (to managed a group of changes within none parent repo), but since Composer doesn't support them, you can check out the answer in "How do I use a Git submodule with a Composer loaded library?".
The approach 1 remains the better one in term of long-term manageability and flexibility, but might require substantial re-architecturing work at first.