Back in the days of yore there was FTP, and it was OK (don’t fool yourself, it was never ‘good’). And we used FTP to upload files to our servers and we messed things up and we overwrote good code with bad and well... we made a mess.
Then some genius (bless his or her soul) thought of creating a system that you could use to maintain a history of every version of your code. They also thought it would be neat if it supported more than one person working on the code and could also give you ‘diffs’ between two versions.
There are a fair number of systems providing these features and they are known as Version Control Systems (VCS). Subversion (SVN) is one of those and it’s what I’d like to discuss here.
I want to preface this blog with stating that I didn’t scour the Internet for all the best practices with version control, and I didn’t spend time working up some sort of rubric for determining which version control system is best. I decided to shoot from the hip and tell you a bit about my version control experience, why I like SVN and why I think it is a great version control system.
I expect we’ll have another blog here soon about a VCS called Git. I’ll let you make up your own mind about which you think is best suited for your needs.
When I started with version control, I was using Windows, and if you use SVN on Windows you’ll likely find yourself using Tortoise SVN. Tortoise is a great GUI program that takes all the mystery out of SVN. I’ll get into some of why I like it later, but suffice to say that it makes version control brain-dead simple and leaves little room for error.
Back when I got my start SVN was on version 1.6, but our server was on 1.4. We ran into a host of issues that made me wonder if it was worth all the pain, but once I convinced the IT team to upgrade to 1.6, things got a lot better. Now SVN is on 1.7 and 1.7 clients can talk to 1.4-1.7 servers, but they’ll run the best if both the client and the server is running on 1.7.
You’ll note two words I used in the previous paragraph: client and server. SVN is very much a centralized system with distributed clients (typically your devs) pulling code down from the server, making changes, and then committing those changes back. This lends itself well to simple scenarios where dev teams keep to a simple trunk/branch/tag workflow.
In a trunk/branch/tag workflow, the trunk is the wild, wild west (in some systems trunk is called HEAD or master—the concept is the same). All rough and new code goes into trunk. At some point the dev team (or more likely the dev team lead) decides that it’s time to get things solidified and cuts a branch from the trunk. What this means is that a snapshot of the trunk at a given time is taken and that snapshot is the foundation for future changes.
The branch is worked on and stabilized so that it is a reliable version of the code and when it is satisfactory, a tag is cut (I’ve always wondered why the metaphor wasn’t just continued to ‘leaf’) and that tag is deployed to production systems.
While all of this is going on development is still continuing in trunk, but the branch may be getting tweaks and fixes to that same code. At some point you’ll want to pull all those changes back down into trunk so that the next time you cut a branch they are present. This is called a merge.
There’s a lot of fear, uncertainty and doubt about merging in SVN. Older versions would often have conflicts and could cause a developer to lose their mind as they reviewed each line of the code diff that the merge consisted of.
In newer versions of SVN it is much more reliable and if you use Tortoise on Windows or Versions on the Mac there are great diff tools that will pop up whenever there is a conflict in the merge process and let you resolve it.
One thing that you don’t want to lose when you do these merges are all of the commit messages you’ve made to the branch as you fixed things up. Tortoise supports this natively, but if you are on a ‘nix system you’ll need to use the python-based tool called ‘svnmerge’. This allows you to move the commit messages back to trunk when you move the code back.
Something that is possible in SVN now that newer versions merge better is the ability to create feature branches. Feature branches are often used when a developer is working on code to create a specific feature that may interact with another dev’s code. Imagine you have a module named ‘foo’ and in that module you wanted to alter one of the page callbacks to output some new information. Another developer is also working in module foo to change some of the HTML output and will likely touch the same callback you’re working on.
If both devs work in trunk, or the same branch, they’re going to step on one another’s toes. One way to deal with that is to simply hold off on committing changes, but that means that the code is just on the developer’s laptop and could be lost.
What the developers can do instead is copy trunk, or the current branch, to a new branch (we name ours after our JIRA stories) and then the developers commit there. Once the work is ready it is merged back to the source location, or sometimes to an integration branch first, and then back to the source.
One thing that helps with SVN is to cherry pick commits when you merge. This means that rather than telling SVN to merge an entire branch with another branch, you choose the specific commits you wish to merge over. This makes for a much faster and more reliable merge.
Now we get to why I really like Tortoise SVN (other GUI SVN tools are good too, but Tortoise is free and awesome). Tortoise shows you in your file browser whether or not a file has been altered by putting a little check or an x next to it. This way you can tell, at a glance, if files in a code repository are altered. Also, whenever you commit a change, you get a UI showing what files have changes, you can right click on any and see a diff of the changes, revert a specific change, and then commit only the files you wish to commit.
There’s no possibility for mis-typing a commit number; uncertainty about the changes you’re committing; or concern about missing a file that is going to be committed.
There are a lot of arguments to be made for and against various version control systems, but If you need something easy to learn, that functions well in simple use-cases while extending to complex ones, then SVN is a great way to manage your code.