Managing multiple local Mephisto repos with svk

August 19, 2006 @ 04:07 PM Posted by octopod

I’m loving using Mephisto as my blog engine. Justin has done great work on the interface and Rick’s code is of his usual standard. There’s a lot more great stuff to come which I’m really looking forward to. In fact I’m loving Mephisto so much I’ve decided to use it as the blogging engine on a client project. This project doesn’t require very advanced blogging, but it does require that it’s integrated with the main site with seamless user registration and multiple sites. I’ll write more about that when I do it, but first I want to show how I setup my development environment so I can track changes to Mephisto trunk, make any local changes I require and deploy using Capistrano.

My requirements were:

  • Have multiple local copies of Mephisto I can make versioned changes to
  • Merge upstream changes from the Mephisto trunk into my local versions
  • Be able to deploy with Capistrano

I initially tried this with darcs, but came to the conclusion that svk was a better choice as it works better with Subversion. I’ll go through the process of how I set this up here, I’m assuming there’s no local SVK repos already setup. If there is you may have to modify the steps below to fit.

First up is setting up an svk mirror of the Mephisto trunk. I ran the following to setup the mirror to pull from:

1
2
3
4
5
6
7
8
    $ svk mkdir //pull_repositories
    Repository /Users/chris/.svk/local does not exist, create? (y/n)y
    $ svk mkdir //pull_repositories/mephisto
    $ svk mirror http://svn.techno-weenie.net/projects/mephisto/trunk  //pull_repositories/mephisto/trunk
    $ svk sync //pull_repositories/mephisto/trunk
    Syncing http://svn.techno-weenie.net/projects/mephisto/trunk    
    ... lots of output ...
  

Syncing the Mephisto repository will take a while the first time you do it. The next step is to create a local svk branch to use. I tested this process out with my personal blog so I’m going to create a local branch called personal.

1
2
3
4
    $ svk mkdir //local
    $ svk mkdir //local/mephisto
    $ svk cp //pull_repositories/mephisto/trunk //local/mephisto/personal
  

So now there’s a local copy you can checkout with svk co //local/mephisto/personal, make changes to and checkin with svk ci. See the installation instructions on the Mephisto wiki for how to proceed.

We won’t be able to deploy this yet, as Capistrano doesn’t support svk. What’s needed is the ability to push the local branch out to another subversion repository that Capistrano can use for deployments. You’ll need to make a new subversion repo wherever you usually keep them.

1
2
3
4
5
    $ svk mkdir //push_repositories
    $ svk mkdir //push_repositories/mephisto
    $ svk mirror (url to your svn repo) //push_repositories/mephisto/personal
    $ svk smerge --baseless //local/mephisto/personal //push_repositories/mephisto/personal
  

You can checkout the subversion repo with svn and you’ll see a copy of your local branch. You use this repository as your repo in your deploy.rb.

To help with the svk stuff and all for automatically pushing the latest local changes to the subversion repo when deploying, I created a lib/tasks/svk.rake that looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    app_name = File.basename(File.dirname(Dir.pwd))
    install_name = File.basename(Dir.pwd)

    local_repo = "//local/#{app_name}/#{install_name}"
    push_repo = "//push_repositories/#{app_name}/#{install_name}"

    namespace :svk do
      desc "Get latest from upstream"
      task :pull do
        system("svk pull")
      end

      desc "Push local svk branch to remote svn"
      task :push do
        system("svk smerge --incremental --log #{local_repo} #{push_repo}")
      end
    end    
  

And added the following task to my deploy.rb1

1
2
3
4
5
    desc "Push the latest svk code to the svn repo and set the svn revision number"
    task :before_update_code do
      system("rake svk:push")
    end
  

That should be everything setup. You can now hack away on Mephisto to your hearts content in as many different branches as you want. Have a read of the svk manual to see what else is possible. For example, if you’ve some patches to contribute back, you can create a new local branch, apply just those patches to it, make sure the tests pass, then svk diff to create a patch.

1 Due to the way I have my svn setup I needed to do some other stuff to stop it trying to find the latest revision. If your deploy gets stuck in a loop trying mention it in the comments and I’ll add that code to the article.

August 24, 2006 @ 02:48 AM Comment by Isaac

When I try to run:

“svk smerge—baseless //local/mephisto/personal //push_repositories/mephisto/personal”

I get the following error:

Transaction is out of date: Out of date: ’/personal’ in transaction ‘4’ Please sync mirrored path /push_repositories/mephisto/personal first.

Possibly I have my svn setup the same as yours?

Could you please post the code that got it working for you?

Regards, Isaac

August 24, 2006 @ 09:28 AM Comment by Octopod

Hey Isaac, I didn’t run across that. Maybe I missed a step in the instructions.

Try running:

svk sync //push_repositories/mephisto/trunk

Then run the smerge command again. Let me know if that works and I’ll update the article

September 16, 2006 @ 02:54 AM Comment by Peter
What are the advantages here over using svn_load_dirs.pl on a vendor branch in Subversion?
September 16, 2006 @ 09:20 AM Comment by Peter
Hi, I realized that my last post is not very detailed. I was hoping someone could help explain why this is better than using an svn vendor branch (aside for the ability to work offline). I understand the need to mirror repositories for distributed teams. However, to the untrained eye, the setup described above seems to have some problems. My main concern would be that the main development repository is now located on a client machine. So if you loose that client, all you have left is the original svn repository on techno-weenie.net and the svn repository that you were pushing code to. Would your push target svn repository retain all the same history data the local svk depot contained? Also, it makes sense that the person in charge of merging vendor drops must use svk to. But does everyone on the team now need to use svk on a local mirror, or can some developers simply work out of the push-to svn repository? What am I missing here? Peter
September 17, 2006 @ 06:27 PM Comment by Octopod
Hi Peter, sorry for the delay in replying, I was off at RailsConf Europe. The main advantage for me is the ability to work offline and make changes I can check in without having access to technoweenie's svn repo. Sure the changes are local to my machine, but I back that up. I'm making changes to the main app, not a library so I don't think the vendor drop concept would work. Currently the team is one person, me, so dealing with it being svk only isn't a problem. If I ended up doing lots of work with this, I'd probably use svk to create a local svn mirror and have other people work with this. The push repo contains the svk changes with their log messages. Hope that helped.
September 18, 2006 @ 12:57 AM Comment by Peter
Thanks for your response Chris. You have intrigued me enough to attempt setting it up.