How could I have lived for so long without knowing that I could set up my command line with vi key bindings? Well, for anyone else who uses vi and bash, here’s the secret…

Create ~/.inputrc

set meta-flag on
set input-meta on
set output-meta on
set convert-meta off

add this to your .bashrc

set -o vi

Thanks Adam!

I’ve been learning git lately and it seems much easier to use than subversion for branching and merging, but I still have yet to become adept at looking at a file history. It seems to be the way that a lot of projects are moving, especially for rails and open source projects; besides, all the kids are doing it, so I figured I would follow the trend. In addition to using it pretty simply for small projects, I’m moving a project from subversion to git, which turn out to be a little bumpy, so I thought I would share.

I started with these awesomely simple instructions to cleanly migrate your subversion repository with the addition of a handy script to automatically create an svn.authors file.

This all seemed to go well, until we tried to run the code and learned that svn-git failed to fetch a directory! svn-git really ought to warn you somehow that it doesn’t support fetching externals. This I learned by noticing that the svn log had no checkins of those files and then saw when I did a clean svn checkout that it was fetching externals for the vendor/plugins directory. Of course that makes a lot of sense, but I didn’t set up the svn so I didn’t know. Then I spent some time wandering through the wilderness of blogs and mailing lists learning about svn externals and git submodules, and I found some interesting clues:

After all of that, I stepped back and thought about what I actually needed for this project. We’re currently at 2.0.2 and planning to upgrade to the the latest, and it turns out that all of the plugins that we’re currently tracking on subversion have moved their latest versions to git. So, I decided to just pull in the vendor/plugins directory verbatim, detaching the external reference, and move to git submodules as we upgrade. What I really wanted to do, but didn’t see how to, was to reference the plugin code as an http URL and keep as a submodule, so that I would have a handy reference to source location and revision.

$mkdir project-tmp
$cd project-tmp/
$git-svn init svn://myserver/project/trunk
$git config svn.authorsfile ../svn-users.txt
$git-svn fetch
Checked out HEAD:
  svn://myserver/project/trunk r999

$cd vendor
$svn co svn://
$cd plugins
$rm -rf .svn  
$git add .

$cd ..
$git clone project-tmp project
$rm -rf project-tmp

So, I’ve been working to migrate my ultrasaurus weblog from Movable Type to WordPress (this one will come later). Since all the links were changing anyhow, I decided to move from ugly numbered permalinks to pretty links based on the title of the post. I only had a few hundred posts, but enough so I didn’t want to be doing it by hand. Since I’m learning Ruby and infatuated with it at the moment, I wrote a Ruby script to generate the .htaccess directives.

In case this would be helpful to anyone else, here’s the code:

[sourcecode language=’ruby’]
require ‘date’
require ‘find’

Find.find(‘./archives/’) do |fname|
# puts fname
date_string = “”
title = “”
next if, “r”) do |f|
f.each_line do |line|
if m = line.match(“(


)”) then
date_string = m.captures[1]
elsif m = line.match(“(

)(.*)(</h3)") then
title = m.captures[1].downcase

# for some reason my mt archives include some old drafts with no titles
next if title == ""

oldfilename = File.basename(fname)

# 1) remove chars that I think wordpress removes
# 2) change spaces to dashes
# 3) handle this case to avoid —
# Emmy Award for Outstanding Lead Actress – Miniseries or Movie
# also avoid — which I saw in my data, but not sure why it was there
# 4) remove trailing dash if there is one
# Thank you ruby-talk
title = title.gsub(/[(,?!'":.+=/)]/, '').gsub(' ', '-').gsub('–','-').gsub(/-$/, '')

# get the new path to the entry, like "/2003/03/brand-new-weblog/"
date = Date.parse(date_string)
newpath = sprintf("%d/%02d/%s/", date.year.to_s, date.month.to_s, title);

# we want something like this:
# redirect 301 /old/old.htm

output = "redirect 301 /sarahblog/archives/" + oldfilename + "" + newpath
puts output

end # loop thru files in directory