Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maintaining two very close but separate lines of development under svn?

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:

  • The trunk branch is our standard version that is deployed for ordinary customers
  • The 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.

like image 994
Ashkan Kh. Nazary Avatar asked Oct 22 '22 15:10

Ashkan Kh. Nazary


1 Answers

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.

  • In object oriented code, you can usually have base class with the common logic and per-variant custom derived class with just the logic specific to that variant that is either conditionally included in project or conditionally instantiated.
  • Most programming languages support some form of conditional compilation, Java being notable exception.

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).

like image 126
Jan Hudec Avatar answered Oct 27 '22 18:10

Jan Hudec