Look at techniques such as Dependency Injection, and Feature Flags. Each deployment should only be a different configuration of Feature Flags. Otherwise, you're overcomplicating things.
Agree. The problem with forking or having separate long running branches for each customer is that you end up maintaining n slightly different mutations of the same system. X got a fix for a recurring issue, the fix has been copypasted or cherry-picked to Y. Y got a different feature . Z didn't get the previous patch because this customer does not really use the given feature. Another developer finds a new, common problem and now, he must create 3 different fixes in 3, slightly different systems.
Managing feature flags are not always easy, but creates significantly less maintenance overhead than managing multiple mostly similar, but different codebases.
Managing feature flags are not always easy, but creates significantly less maintenance overhead than managing multiple mostly similar, but different codebases.