Recently I came across Lucas Ward’s blog post on a maturity model for source control which resonated strongly with me and provided the inspiration for this post. I realize that the following may not necessarily represent an extreme example nor a “typical” project and is hopefully boring for most audiences (because using source control should go without saying). Never the less, my experience has only reinforced the importance of source control with me for a project of any size to leap frog basic problems in maintenance and deployment and I wanted to share my experiences.
When I joined my current company, one of my first projects was to help migrate a portion of a 10 year old code base into an existing repository. The majority of the code base was already in a TortoiseSVN repository, however, one language remained outside source control. Originally, there were just a few developers who could rely on word-of-mouth oversight to manage changes without the need for tracking changes in a repository. The primary reason for not including the code for this language in the repository from the beginning was that there was not an easy way to tie the operational code (which lay within the database environment) to a repository checkout with the editor provided by our database vendor.
Over time, the source control method had evolved to a single “Master” environment for all shared code and 130+ client specific Test-Production environments. Individual developers were responsible for making sure the Master and Test environments were maintained with the latest changes. My own discovery rate of missing code was at least 2 significant changes per month. This was most commonly due to someone copying a stale version of a routine back into the Master environment, or fixing something for a client while neglecting to apply the change to the Master environment.
With continued growth of the code base and new developers joining the flock, getting this last portion of the code base into source control became imperative to keeping our sanity and reducing the amount of time we had to spend manually backing up and comparing routines as we did development, lest we suffer the consequences of copy/paste. (I am also of the belief that a lack of source code control constitutes a major source of Technical Debt)
First, we needed to create a way to interface with our Tortoise repository from our database environment and the editor our DB vendor provided. These were some of the bumps we encountered along the way in the course of developing:
- The first version of our database we tried developing hooks for did not provide enough support for interacting with a repository from within our code editor. This required us to upgrade 2 major versions , which in and of itself was a significant undertaking because one of our test servers contained about 100 of our approximately 130 test deployments. Several of the environments failed to upgrade without assistance.
- We started investigating a 3rd party library for interfacing with a repository before we realized we could interface with tortoise directly without adding in extra application dependencies. No need to add to your technology stack when it isn’t necessary.
- Our hosted repository (Trac) was a major version behind what was then the current major version of SVN and would cause ‘differences in version’ errors during some of our initial testing. We just decided to have Trac upgrade the version of our SVN repository.
- Just finding the time to develop/test these amidst other development and support pressures was a major challenge. Infrastructure improvements tended to take a back seat to client and support desk demands.
Then we needed to figure out what our repository structure would be and how to build/cull our initial commit from the 130+ deployments already in existence. We decided to make a directory structure that resembled our current deployment method (one folder for all “core” code, and one folder per client deployment for dedicated code and configuration). We also took the migration as an opportunity to archive + remove any code and deployments that were no longer in use and were simply persisting as clutter.
Finally, after many test runs (and almost 2 years from when we first embarked), it came time to make the migration with our master and test environments. After several months of use, we have shaken out the major bugs, coded around several undiscovered special cases, and have started implementing more SVN functions beyond our initial set. Even though we now have our code in a repository, doesn’t mean that it is all sunshine and lolly-pops. Our test-to-live deployment remains a manual process. Developers can still make fixes directly in production environments without committing them to the repository, either due to client pressure or lack of testability in Test.
I’m glad that we finally have some measure of source code control now. Generally, it has reduced some of the work effort in checking and maintaining the core code base. While there are still a few ways to get around this, the occurrence of lost code has been greatly reduced.