I previously posted a method to move a svn project to git permanently; i.e., without keeping the two-way bridge between svn and git that git-svn
is usually meant to provide. This method involved git-svnimport
. It had the advantage that it somehow transposed the concept of tags from svn to git (in svn tags are really a special kind of branch while tags in git are just labels associated with a commit). But sometimes before git v. 1.6, git-svnimport
disappeared from the git suite. This is a new method using git-svn
which gets all the information out of svn (converting svn tags to git branches) and erases all traces of the original git-svn
bridge. Thanks to the folks on the #git channel at irc.freenode.net for their help in getting this working.
I will describe a real-life case for the sake of clarity: the svn repository contains several projects which are each organised with the standard svn layout (trunk, branches, tags). Here the repository is models_larvae
, the project is opsime
, and it has one tag called opsime-C-original
and one branch called ovm-advection
.
First, get the svn history into git. This part is quite network intensive and is much faster when done from a local copy of the svn repository.
git svn clone -s --no-metadata file:///path/to/svn/models_larvae/opsime/
cd opsime/
Without the --no-metadata
option, git svn
adds a reference to the svn revision number in every log message. For example, the end of the log message for revision 119 would look like
git-svn-id: file:///path/to/svn/models_larvae/opsime/trunk
1ec6eabb-110e-47cd-b2e3-95104d50c16c
Using this option makes the git repository a bit more ignorant of its svn ancestor but it can be a problem if a log message refers to a specific svn revision by number.
The initial clone imports everything including svn branches and tags, however
git branch
* master
I.e., in git, only a master
branch is available. The svn-related branches and tags are actually remote branches in git (which makes complete sense since they are created remotely in the repository and not locally by you). And indeed
git branch -r
ovm-advection
tags/opsime-C-original
trunk
So we need to copy those remote branches as local ones.
git fetch . refs/remotes/*:refs/heads/*
And now
git branch
* master
ovm-advection
tags/opsime-C-original
trunk
Now, let us erase the remote branches as well as the local trunk branch which is redundant with our git master
branch.
git branch -rd ovm-advection tags/opsime-C-original trunk
Deleted remote branch ovm-advection (e14fcc5).
Deleted remote branch tags/opsime-C-original (7270a66).
Deleted remote branch trunk (33c88fd).
git branch -d trunk
Deleted branch trunk (33c88fd).
This is probably easily automated for repositories with more remote branches and tags (with something such as for branch in `git branch -r`; do git branch -rd $branch; done
). Now the tree looks clean
git branch
* master
ovm-advection
tags/opsime-C-original
Finally, we need to remove the git-svn
configuration options and folders
git config --remove-section svn-remote.svn
rm -Rf .git/svn/
And, after all those steps, git is unaware of anything related to svn
git svn log
fatal: bad default revision 'refs/remotes/git-svn'
----------------------------------------------------
And, to conclude, here is a one paragraph summary, ready for copying and pasting, of the steps following the initial git svn clone
git fetch . refs/remotes/*:refs/heads/*
for branch in `git branch -r`; do git branch -rd $branch; done
git branch -d trunk
git config --remove-section svn-remote.svn
rm -Rf .git/svn/
0 Response to “Moving from subversion to git permanently – take 2”