@madpilot makes

Working with branches in Subversion

I know that Git is the flavour of the month in regards to version control at the moment, but I still use Subversion (SVN) for my day-to-day version control needs. And since it is still very popular, I think this quick tutorial still has it’s place. Today, I was asked by a client to show them how to branch a SVN repository so they could start making some major changes to their application with out running the risk of breaking the release version.

The scenario works something like this: You have finally launched your application and everything is purring along nicely. You decided to start working on the next iteration, which has some major changes that WILL break things initially. You start working away, and find yourself half way through the changes when you get a call from an irrate customer who can’t complete their transaction because of an obscure edge case bug that you missed. The dilemma that you have is that your source base is in a state of flux, and you can’t release it, because in it’s current state, it doesn’t work. Wouldn’t it be great if you could have maintenance version of your application that you could make the fix on? Enter branching.

Firstly, a bit of terminology. I’ve used the word “branch” a couple of times. The analogy is simple – you have a core line of code (The “trunk”) and you can have concurrent lines of code that “branch” from the trunk. One of those branches may well be our “stable” branch, meaning that the only changes that can occur are bug fixes – ie NO new features. As with any system, there is more than one way to fell a tree, but this is the system that I generally use.

So how do you do it? When I create a new SVN project, I like to add a trunk directory, and a branches directory. With in that branched directory, I add another directory called stable (let’s pretend my SVN server is at svn.myserver.com):



# Create a new project - tedious stuff like locking down access omitted for clarity

svnadmin create new_project

# Now head over to your working directory, and check out the initial version

svn co svn://svn.myserver.com/new_project

» Checked out revision 0.

cd new_project

mkdir branches

mkdir trunk

# Now to add the new directories to the repository

svn add branches trunk

» A         branches

» A         trunk

svn commit -m "Adding initial directories"

» Adding         branches

» Adding         trunk

»

» Committed revision 1.



Now we have our working copy setup and committed back to the server, you can start work on the trunk. Cut scene to the day before go live. You are pretty happy with how the trunk is looking, and you would like to branch the code into stable. For this we use the copy command



svn copy svn://svn.myserver.com/new_project/trunk svn://svn.myserver.com/new_project/branches/stable -m "Branching stable"

» Committed revision 10.

cd stable

svn update

» A    stable

» Updated to revision 11.

And we are done! Now you can continue on your merry way and change code in trunk with out affecting your stable release. Once you are happy with the next version and you’re ready to create your next stable branch from your new feature rich trunk, you can “merge” your changes from trunk into stable:



svn merge svn://svn.myserver.com/new_project/branches/stable svn://svn.myserver.com/new_project/trunk -m "Merging trunk changes into stable"

» A    new_file_that_is_in_trunk.txt

And of course it works the other way – say you found that obscure edge case bug in stable, and you have fixed it, you would want to merge the change back in to trunk, so you don’t introduce any “regression bugs” (Bugs that you fix, then inadvertently re-introduce by changing code). All you need to do is flip the order of the two URLS:



svn merge svn://svn.myserver.com/new_project/trunk svn://svn.myserver.com/new_project/branches/stable -m "Merging edge case fix from stable"

» M    fixed_file_from_stable.txt

There you go! Easy as pie – let’s just hope you don’t get to many conflicts that you need to manually resolve. It’s always a great idea to test you code again after a merge, just to be sure everything works as expected.

2 comments

  1. Nice to see SVN still getting some love!



    I do things a little differently.



    The way that I was "taught" SVN is that that your "stable" branch would actually be a tag, and that each stable release that you make is another copy of your trunk into tags. I can see benefits in this, especially if you're managing multiple "live" versions of your code, and need to be able to work on a known release.



    I tend to use branches for major things in development that may never come to fruition (or will frequently be broken), tags for each stable release, and trunk as the most up-to-date (but fully working) copy.



    I also try to be pretty anal about never checking in a broken trunk, but as a branch tends to be used by just a single developer, I'm happy to test broken code into a branch just to keep some history.



    To each his own I guess. I think the most important points someone needs to take from your post is that your repository needs to work for you, and to try to keep your trunk clean and working as much as possible.
  2. Jason: Absolutely - and that schema works for projects that have definitive "Frozen versions".



    The reason I suggest the method I do is because many web projects don't have versions as such - they only have a "live" version and a "development" version.



    Horses for courses really.

Leave a comment