Git history rewriting

A little off-topic, but I just spent hours trying to get this to work. Basically, I’m moving a bunch of Rails plugins over to github and need to edit the history to move all files up one level. For example, PackR looks like this in SVN:

trunk
  packr
    lib
    tasks
    test
    ...
branches
  3.1
    packr
      lib
      ...

It’s like that so that when you call script/install http://.../packr/trunk/packr it creates the right directory in vendor/plugins. When moving to Git I wanted to remove that superfluous packr directory, and the example in Git’s docs didn’t work for me (kept complaining that it couldn’t stat index.new). Here’s how I got this to work, it’s probably not the most elegant thing since my knowledge of bash scripting and sed is slim to non-existent, but hey it works:

git filter-branch --tree-filter ' \
    for dir in $(git ls-files | \
            sed -r "s/^packr//g" | sed -r "s/[^\/]+$//g"); \
        do mkdir -p .$dir; \
    done; \
    for file in $(git ls-files | sed -r "s/^packr//g"); \
        do mv -f packr$file .$file; \
    done' \
--tag-name-filter 'cat' HEAD

Eh voila, PackR is up on github!