Creating a svn.authorsfile when migrating from subversion to git

There are plenty of tutorials already out there on how to migrate a subversion repository to git. This is the first one I found, and it seems pretty good: Cleanly Migrate Your Subversion Repository To a GIT Repository

All the tutorials I found generally tell you to write the svn.authorsfile by hand. This is easy enough to do, if there are only a handful of authors, and you know exactly who they are.

The kink is if you forget an author, git-svn bails out when it sees an author that wasn't in the svn.authorsfile. You have to tweak the file, and start over, hoping that you got them all.

This can be a fairly time consuming process, considering that a repo with some 500 commits took about 15 minutes to migrate.

Wouldn't it be nice if there was a way to automatically generate a svn.authorsfile based on the subversion history?

I thought so, so I wrote this up:

#!/usr/bin/env bash
authors=$(svn log -q | grep -e '^r' | awk 'BEGIN { FS = "|" } ; { print $2 }' | sort | uniq)
for author in ${authors}; do
  echo "${author} = NAME <USER@DOMAIN>";
done

Run this inside an subversion checkout. It outputs a template for the svn.authorsfile to the console, so you just need to paste it into a document, and fill in the names and email address for your authors.

Managing svn:ignore with impunity

Managing svn:ignore has always annoyed me. After using git for the past few months, it bugs me even more now.

I think I've come up with a simple way of coping. That, or I totally stole it from someone else on the internet, without realizing it. It's hard to keep track of these kinds of things.

The trick

Here's what you do:

  • Create a .svnignore in the top of your project.
  • Make a list of files/wildcards you care to ignore
  • Save it

Now, from the top of your project, you can do:

$ svn propset svn:ignore -F .svnignore  .

If one were to wordify this command, it's be something like "Set the svn:ignore property from the contents of the .svnignore onto the current directory." It can really be any file, but I kinda like this convention.

It is also likely you will want to keep .svnignore under source control.

Now automate it

It's usually best to automate when possible, since even this simplied way of managing ignored files might get tedious. Or maybe someone coming onto the project doesn't have our level svn-fu.

We already have a lib/tasks/svn.rake that has a few tricks in it, so I figured on expanding it. Here's the original:

namespace :svn do
  desc "Adds all files with an svn status flag of '?'"
  task(:add) { system %q(svn status | awk '/\\?/ {print $2}' | xargs svn add) }

  desc "Deletes all files with an svn status flag of '!'"
  task(:delete) { system %q(svn status | awk '/\\!/ {print $2}' | xargs svn delete) }

  desc "Writes the log file to doc/svn_log.txt"
  task(:log) do
    File.delete("#{RAILS_ROOT}/doc/svn_log.txt") if File::exists?("#{RAILS_ROOT}/doc/svn_log.txt")
    File.new("#{RAILS_ROOT}/doc/svn_log.txt", "w+")
    system("svn log >> doc/svn_log.txt")
  end
end
I added a new task that looks like:
desc 'Updates svn:ignore from .svnignore'
task(:update_svn_ignore) do
  system %q(svn propset svn:ignore -F .svnignore .)
end
Now we can tweak `.svnignore` to our hearts' content, and then just run:
$ rake svn:update_svn_ignore
(in /Users/nichoj/Projects/boston_rb)
property 'svn:ignore' set on '.'

Awesome.