Ever wish you’d branched first?


So you’re hacking away at a working copy and you want to check things in. The problem is, your working copy is based on the trunk and your changes don’t really belong on the trunk.

Maybe the development trunk has been locked down for a customer release; maybe you’ve started work on a simple feature which turns out not to be so simple, and you’d like to phase your changes in on a private branch; maybe you want to share work-in-progress with another team member — whatever the reason, you wish you’d branched the code before you’d started working on it.

This note describes three ways, ugly, bad and good, to adapt to this situation.

Brute Ignorance

Just check the changes in anyway. In this code snippet and the ones that follow, we’ll assume your working copy reflects a repository URL svn://svnserver/trunk and is located in a subdirectory called trunk.

$ svn commit -m "Changes" trunk

Yes, I have seen this done. Sometimes developers use the repository trunk a bit like a private fileshare. Get something working on Windows. Check it in. Then login to a Linux machine, update, see if it works there. Someone else will probably fix up Solaris …

There has to be a better way. Developers who adopt this technique deserve an ASBO slapped on them.

Brute Force

Make the branch. Check it out. Patch across changes from your working copy.

$ svn copy -m "My new branch" trunk svn://svnserver/branches/new-branch
$ svn checkout svn://svnserver/branches/new-branch

The code sample uses the working-copy-to-url flavour of svn copy, which means you’ve correctly branched from the BASE revision you were working on. Depending on circumstances, you might have preferred to update your working copy first, or branch from the tip of the trunk using the url-to-url flavour of svn copy.

Patching changes between your two working copies may not be trivial. Some are happiest using a graphical file browser to drag and drop files from trunk to branch. Svn diff followed by patch does better.

$ svn diff trunk | patch -d new-branch -p1

Both techniques fail to copy any property changes across though — and please don’t try digging into the .svn directories to remedy this. Again, there’s a better way.

Branch and Switch and Go

The best thing to do is simply create the branch and switch to it. Traffic to and from the server is minimised, local disk access is reduced, no changes are lost.

$ svn copy -m "My new branch" trunk svn://svnserver/branches/new-branch
$ svn switch svn://svnserver/branches/new-branch trunk
$ mv trunk new-branch

You’ll notice that at the final stage we rename our working copy to reflect its new purpose. This isn’t strictly necessary but may save us from future confusion.

Now you’re on a new branch and can check your changes in as desired.