We have our project under svn and everything is going all and well. Recently a major customer asked us to do some quite specific customizations for them that requires coding and stuff (could not be done using configuration or deployment). We decided to maintain two separate lines of development:
trunk
branch is our standard version that is deployed for
ordinary customers arsh
branch is for this customer and is under ongoing development separate from what is going on in the trunk
Now the thing is arsh
should countinually receive updates from trunk
and sometimes features implemented in arsh
are useful in the trunk
. The relation is kinda bi-directional but one direction is quite prevalent (from trunk
to arsh
) but the other one is occasional.
What would be the best way to do this ? work-flows ? best practices ? insights ?
EDIT : We use PHP 5.3, MySQL, Apache and Linux.
Best practice? #ifdef
(or separate implementations of the same interface conditionally included or conditionally dependency-injected by runtime configuration or any other compile-time or run-time conditional)!
Maintaining parallel versions as branches is pain in any version control system. Parallel versions are best maintained using appropriate conditional compilation or runtime configuration technique.
Remember, if you merge a branch A to branch B and than branch B back to branch A, both branches will be exactly identical. This is intrinsic property of 3-way merge. It is exactly what you want for feature branches, but it is totally unsuitable for maintaining parallel versions for different customers.
For keeping versions for different customers instead use conditional compilation.
This approach allows everybody to always immediately check that they didn't break any feature for either variant, either by running tests for all variants or having all variants built and tested by continuous integration server.
You mention PHP. There is no compilation step there, so the configuration will be just runtime. I'd probably create a directory with customer-specific overrides that would conditionally get included in appropriate templates.
Note: I am currently working on a C++ project which is customized for over 20 customers in this manner and it scales just fine. We don't have exactly code per customer, instead we have a set of features that are optional and different subsets are shipped to different customers. That makes it a bit easier to test all features, because we can build a maximal variant and test that. That helps when you grow to large number of features, especially if your project takes a long time to build (our continuous integration build runs about an hour, nightly build 8 hours and building all customer variants takes more than whole day).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With