Like many projects these days, there’s no need to build completely from scratch. Off-the-shelf Open Source applications like WordPress, have changed the landscape. Another situation we encountered with a client once was a code generation platform for PHP. These are fundamentally different things but the way they are managed via version control workflow are the same if you intend to make modifications to them.
Here’s the problem. You install some version of WordPress or generate your baseline application with the code generation platform. Bam, you’ve got a site up and running. Somewhere along the way you’re dissatisfied with the level of control a WordPress plugin can give you or want something the code generation platform just can’t give you. You decide to bite the bullet and make some changes yourself, but this decision is bigger than you realize.
You’ve just complicated the upgrade process. By making changes to files that weren’t intended to be modified in a simple scheme you’ve signed yourself up for extra work. Each time WordPress rolls out a new version or you decide to crank out a new rev of the generated application you now have to incorporate the changes you made into the new code. This may sound like a headache and the worst part is it drives many application authors to simply abandon the upstream changes, which is a horrible idea!
Version Control to the Rescue
Version control gurus recognize this situation as a common scenario where there are two branches of development. Once that model is drawn a paradigm for branching and merging is easy to design and once that paradigm is implemented you can have your cake and eat it too. Which is to say you can make modifications to the WordPress source or the output from the code generation platform, but still plan on upgrading and patching new revs with your modifications.
Designing the workflow
The most important part of this workflow is dedicating a branch for the third-party releases. Each release from WordPress or subsequent output from the code generation platform should be recorded as a commit on the third-party branch. Since your product is based off of these commits it makes the most sense to treat the third-party commits as the mainline of development and your modifications branches of that work.
Ok, so let’s get our hands dirty. We’ll use the WordPress example since the code generation system is a bit more esoteric. However, you should realize from a version control perspective there is practically no difference. Suppose you start out with WordPress version 3.1.0, that’s what moxune.com recently started out with. The very first step is to commit this into your VCS, make it the first commit of the trunk. We’re using Git here so the illustrations will show the master branch.
Building and releasing
The next step is to create a branch and begin working on your customizations. You can merge these back into the master branch if you wish however, it will be a pain to track down that original commit which was from the WordPress group. Remember, what you want to have is one branch which is dedicated to the versions of WordPress itself. So you tag and release off of the branch you’ve just created.
After a few weeks you login to the WordPress admin panel to write a blog post and there’s a message telling you WordPress 3.1.1 is available. Normally you would use the upgrade automatically approach, but you’ve gone in and made modifications that would be overwritten by the update. Thankfully WordPress gives you an option to download the upgrade right there. Once you download the update, head back to the version control system and checkout the master branch. Remember the first (and only) commit on master was WordPress 3.1.0, so we can drop 3.1.1 right on top of it with no conflicts. Now you have 2 commits on master WordPress 3.1.0 and 3.1.1; the branch you created to make your first round of customizations was off of the 3.1.0 commit, so now you have to get them incorporated into the 3.1.1 release.
Again, you could merge your changes into master, but that would clutter up the dedicated WordPress branch in the repository. Instead simply branch off of 3.1.1 and merge from the feature branch you created off the 3.1.0 commit. Now all you have to do is tag and release again and you’ve just done an upgrade that contains your customizations.
And just as an illustration, let’s have a look at what the repository would look like after a third iteration.
Just remember that because you’re using a version control system to help you track and manage two paths of changes to the same product there is no magic that will mesh them together each time you incorporate your changes into the new upstream version of the product. Merge conflicts can and will occur if the upstream product has changed in the same place you’ve made changes in your customized version of the product. Have no fear though, merge conflicts are part of the development process and they aren’t really as bad as folks make them out to be. If a text editor isn’t your favorite place to resolve merge conflicts, find a graphical alternative that suits your fancy.
If you enjoyed this post please consider sharing it!