Wednesday, September 24, 2008

cvs to svn via git

It actually works. The problem: I wanted to take the history of a partial cvs repository into svn. Directly using the tools was out for two points: First, one needs access to the svn repository itself (at least I think so and didn't bother to check because of) second I wanted to patch the paths of the java packages contained therein. Apparently eclipse doesn't quite want to deal with, so it needs to converted to even though the company only owns the former domain.

Anyway, I did not figure out yet how to use git-cvsimport and git-svn both on the same repository sensibly; and I think git-svn rewriting of the commits doesn't quite make that feasible. But the problem already starts with getting both histories to have a common ancestor. Unfortunately git does not have a null commit as the universal base.

Ok, final approach: Create project base directories (the ttb) in svn, do an git svn clone on that. Separately, use git-cvsimport to get the history from cvs into git. (Caveat: The approach does only handle a single linear history well.) Use git format-patch --root commit to get a series of patches, run those through sed -e (which patches directory names as well as imports and package declarations). Then apply (git-am) the resulting commits in the git-svn repository, and git-svn dcommit them. Done.

Except that my link to the svn repository isn't exacly fast at the moment (roundtrip at about a second), and the 60 commits took two hours. svn does not seem to like slow links; a simple tag operation (svn cp trunk tag/some) on a small thingy took me more than a minute over GPRS once.

Here's the complete commands:
mkdir myproj-cvs
cd myproj-cvs
git-cvsimport -p x -v -k -a -d :pserver:krey@localhost:/opt/cvs mystuff/myproj
git-format-patch -o out --root `cat .git/refs/heads/master`
mkdir mod
cd out
for i in *.patch; do sed -e s:company_name:companyname:g $i >../mod/$i; done
cd ../..
svn mkdir http://localhost:4080/repos/mystuff/myproj -m 'base dir'
svn mkdir http://localhost:4080/repos/mystuff/myproj/trunk -m 'trunk dir'
git-svn clone -s http://localhost:4080/repos/mystuff/myproj
cd myproj
git am ~/myproj-cvs/mod/*
git svn dcommit

No comments: