converting an svn project to git
To get in the right frame of mind, don't think of exporting your entire svn repository, but rather export project by project. Export the trunk of your projects and forget about the branches. If you need data from the branches, merge it first.
set up svn to git user mappings
- create a text file somewhere (~/.git-svn-users) to map the svn users to git users
jdoe = John Doe <jdoe@example.com>
- alter your global config file (~/.gitconfig) to use this user mappings file
git config --global svn.authorsfile ~/.git-svn-users
my current method
- use git svn to clone your svn project to a temporary directory
git svn clone svn://repo/path/to/myproject myproject_tmp --no-metadata
- UPDATE - it seems as if the error below could be related to Tortoise and/or the TortoiseSVN cache running at the same time (we are writing these conversions directly into an svn working copy)
- if you get an error like the following, just ctrl-c the operation, delete the temporary directory, and try it again
20592274 [main] perl 3584 C:\cygwin\bin\perl.exe: *** fatal error - unable to remap C:\cygwin\bin\cygserf-0-0.dll to same address as parent: 0xA80000 != 0x1390000 20597997 [main] perl 3572 fork: child 3584 - died waiting for dll loading, errno 11
- cd into myproject_tmp, and either run gitk or git log to review the author names and emails, to make sure your svn user mappings worked; then cd back up one directory
- clone the temporary git project directly to a shared location
git clone --bare myproject_tmp /path/to/shared/git/myproject.git
- remove the temporary project
rm -Rf myproject_tmp
- clone from the shared git repo so you have a direct merge setup with the master branch
git clone /path/to/shared/git/myproject.git
- (optional) compare your current svn working copy with the final git working copy, then remove the project from svn
If you are lucky (no errors), steps 1-5 can be automated with a simple bash loop:
for file in {project1,project2,project3} do git svn clone file:///path/to/svn/repo/project/${file} ${file}_tmp --no-metadata \ && git clone --bare ${file}_tmp /path/to/git/shares/${file}.git \ && rm -Rf ${file}_tmp/ \ && git clone /path/to/git/shares/${file}.git/ done
old method
- create a temporary project directory, and change to it
mkdir myproject_tmp cd myproject_tmp
- initialize an empty git repository
git svn init http://host/path/to/your/svn/repo/project/trunk --no-metadata
- for some reason I've recently had trouble starting this process with git svn init, so I've been doing git svn clone instead. It looks like this:
git svn clone file:///cygdrive/h/svn/project/trunk myproject_tmp --no-metadata
- set up the user file for mapping
git config svn.authorsfile ~/Desktop/users.txt
- import the svn repository
git svn fetch
- change up one directory, and clone this newly created repository (this cleans up all svn stuff)
cd .. git clone myproject_tmp myproject
- the myproject_tmp directory can now be removed, and the origin remote
rm -Rf myproject_tmp cd myproject git remote rm origin
- if you want to push this out to a shared repo, you can do it like this
cd /path/to/shared/dir mkdir project.git cd project.git git init --bare --shared cd /path/to/myproject git push /path/to/shared/dir/myproject.git refs/heads/master (you can push other refs if you want at this point, if they should be public) (then I usually git clone from this shared repo for good measure to make sure it all works; your merge paths will work by default too)
- you should also consider that although svn allows empty directories as part of the repo, git does not; we usually fix this by adding empty files named .emptydir in any directory that needs it