Thursday, September 27, 2007

How to Dump Subversive Revisions

Most things in life you can more easily get rid of than an unwanted revision in Subversion. As Simon and Garfunkel sang, there are even 50 ways to leave your lover!

Now why is that so hard? It starts with the principle that revisions should build upon each other, and when necessary can be reversed with another revision, so there should be no need to do so. Subversion therefore is designed never to lose information. What this philosophy does not take into account is that sometimes people make mistakes, or even worse are clueless, and for example start to make changes and commit that to a branch instead of the trunk. Sometimes that happens not only once, but twice!

Of course you can argue that people should not make mistakes and the clueless should never be allowed to work with Subversion. Hey, I'm with you, but you need to start somewhere, and I found that many people find it hard to really understand how tagging, branching, switching and all works, and sometimes need considerable time to get there. So let's face it, shit happens and then we feel a need to dump that in the sewer.

If you ever need to do so, there are two ways. The first way is the official way, which works as follows. By the way, in my example I'm using TortoiseSVN as a client:
  • Make sure you are in the right trunk, tag or branch for which you want to undo some revision.
  • Using "Show Log" find the revisions you want to undo. You can multi-select revisions.
  • Right-click the selection and choose "Revert changes from this revision". This will revert all committed changes locally.
  • Commit that changes (make sure that this time you are committing to the right URL!)
  • If you switched before you started, don't forget to switch back to the HEAD of the trunk afterwards.
The second way is the "hard way", which consists of making a dump of the repository using the svnadmin dump command of the command line tool. When using that, you can make a dump of a specific range of revisions and leave out the revision(s) you don't want using the -r [lower rev[:upper rev]]switch. After that you create a new repository and load the dump into that using the svnadmin load command.

There are a couple of issue with the hard way. First of all, unless you physically remove the folders of the old repository, the old repository will still be there. And people need to be aware that they need to go to a new repository instead. Of course you can tweak that manually by first deleting the folder of old repository and then create a new one using the same name and only after that load the dump back again.

Secondly, the hard way as described, provides no solution for the situation in which you want to remove a revision from some branch while in the meantime a new revision has been created in the trunk, because you cannot provide a set of ranges while dumping. That can be tweaked by making another dump containing the latest revisions and manually "merge" that with the other dump, but that can get complex.

Finally, the repository might have become a big mama and dumping and loading that can take considerable time.

So my conclusion: you need to have a damn good reason not to do it the official way. I'm therefore most interested in the rumor I've heard, that they plan to introduce the svnadmin obliterate command. Hopefully does that allow for removal of a complete revision as well.

No comments: