tags:

views:

162

answers:

2

I want to export a Git repository (G) to a SVN repository (S). S has been initialized with the standard layout (branches/tags/trunk) and G has the development history so far. I followed the advice in the Google Open Source Blog which details how an export GS works. Basically the blog recommends to git-svn clone S into an empty directory, fetch G into a temp. branch and rebase that to "master" thus becoming a second Git repository (G').

I neither want to abandon either files not under source control nor the branches not available on origin. That's why I do not want to continue to work with G' but rather with G. Is there a way to fetch back the new commit representing the layout commit to S? I had no success in trying to merge G' into G (no common ancestry of course).

+3  A: 

You should be able to merge G' and G using git merge --strategy=ours, i.e. by ignoring ancestry and creating a commit that uses the tree of G' but appears to have both commits as parents. The result will be a bit ugly, as the history will contain two copies of each commit, but you should be able to continue working on G seamlessly.

legoscia
I was hoping for something better. Following [1] preserves the history perfectly - the only thing that is needed in addition is the single commit the git-svn needs to recognize *S*. It should be possible to prepend this to my history, given the richness of the git toolkit.
yawn
Prepending is, stricly speaking, not possible, as the identity of a commit depends on the identity of its parent(s). The only way I can think of is to rebase _all_ other branches onto S.
legoscia
Accepted for best effort :-)
yawn
+2  A: 

I'm not sure if there's an easier way to add an initial commit, but there is a fairly easy way to make it appear as though the SVN layout was there from the beginning.

You can use git filter-branch to rewrite the history, so that every file exists under the SVN "trunk" directory, starting from the first commit:

git filter-branch --tree-filter 'mkdir trunk; git ls-files | xargs -I {} mv {} trunk'

You could similarly move files to the tags and branches directories, if you wanted, but how you would decide which files to move there would depend entirely on what the branches are for, or when you want tags added into the history.

Dan Moulding
Very interesting! I will try this first thing in the morning!
yawn
I did not read your answer properly - what I'm really after is the commit representing the initial layout for git-svn, not the layout itself. Nevertheless +1 for filter-branch.
yawn
@yawn: Why not just create the SVN std. layout commit in a new (otherwise empty) Git repo (let's call it repo "T") and then fetch T's master into your G. Then in G, rebase master off of FETCH_HEAD? Any other branches in G that you want to keep and also have descend from the new "initial" commit, you would have to rebase as well (for each branch, you'd have to find the new commit that corresponds to the original base of the branch, though).
Dan Moulding