Today I was pairing with another developer and we got a little ahead of ourselves and committed some rather drastic changes to the trunk/HEAD of our project. After a few more commits it became obvious that we were stepping on several other developer's toes, so we decided to revert trunk back to the revision just before we nuked the codebase.

Unfortunately, nobody knew how to do this, though it seemed like this should be a pretty common task, since just about everyone has wanted to erase the past for one reason or another. It didn't take much Google'ing to find the answer but the syntax was weird enough that I decided to show it here. Thanks Python Software Foundation's How-To for the tips.

The command:

svn merge -r NEW:OLD PATH

Example:

svn merge -r HEAD:101 http://subversion.example.com/project/trunk

Let's say you committed a real stinker at repository revision 20, and, since you've kept committing, the repository is now at revision 22. Here's how to revert HEAD back to the fresh-smelling revision 19. Here's the story:

[~/40withegg]# svn rm test/
D         test/unit/asset_test.rb
D         test/unit/core_filters_test.rb
D         test/unit/tagging_test.rb
...
D         test

Commit it!

[~/40withegg]# svn ci -m'JLM: deleting tests because I am crazy!'
Committed revision 20.

And, after some other craziness, we committed a few more things:

...
Committed revision 22.

Let's undo all of that. First, revert, just to make sure your working directory is clean:

[~/40withegg]# svn revert *

Next, perform the (horribly named for this purpose) svn merge, which will add the clean revision's code to your working directory as changes:

[~/40withegg]# svn merge -r HEAD:19 svn+ssh://joe@example.com/svn/trunk
A    test
A    test/unit
A    test/unit/user_test.rb
...
A    test/referenced_caching_test_helper.rb

Finally, commit the fix:

[~/40withegg]# svn ci -m"JLM: adding the tests back... man that was dumb."
Adding         test
Adding         test/actor.rb
Adding         test/fixtures
...
Adding         test/unit/user_test.rb
Transmitting file data .
Committed revision 23.
[~/40withegg]#

Hope that helps!

I’m in charge of migrating our version control system from CVS to [Subversion}(http://subversion.tigris.org/) and it’s been quite an adventure so far. Subversion (SVN), for those who don’t know, is being pushed by the open source community as the successor to CVS, and it has several compelling advantages over CVS:

  • Atomic commits: no half-committed changes.
  • Ancestor tracking: Rename or copy a file? SVN remember where it came from.
  • Cheap tags and branches: tags and branches don’t really take up any disk space, so feel to go for it. Just follow some good practices.
  • Revisions apply to the entire tree: it’s not “revision 10 of file Foo” it’s “Foo in revision 10 of the repository”.
  • Much more.

SVN has two installation options for actual storage of the repository data: file system (fsfs) or Berkeley DB (bdb). So far, it looks like bdb is…. PURE EVIL. Am I an expert? Nope, but here are the errors I’ve faced so far, before changing over to fsfs this evening:

svnadmin: bdb: PANIC: No such file or directory
svnadmin: bdb: PANIC: fatal region error detected; run recovery

Well, PANIC seems bad to me. I was able to run the following to recover from this:

svnadmin recover /path/to/repository

That seemed to fix that problem. Next up:

Berkeley DB error while opening ‘uuids’ table for filesystem
/path/to/repository
Cannot allocate memory: bdb: Lock table is out of available locker entries

Oh man, that doen’t sound good. After a bit of googleage, I found that I could jack up the locker entries in /path/to/repository/db/DB_CONFIG, but that didn’t work.

I ended up converting to fsfs by doing the following, and it’s been smooth sailing so far:

$ svnadmin create –fs-type fsfs /path/to/new/repository
$ svnadmin dump /path/to/repository | svnadmin load /path/to/new/repository

I’ll be looking at SwitchTower next to see if that will work for us.


1 Comments (from old blog):

At 12/19/2006 7:56 AM, thijs said…

Thanks that worked great! I installed Subversion on Debian with apt-get a week ago and it looks like it’s a very old packag of SVN that still uses Berkeley DB as default storage system.