Search code examples
gitsvnversion-controlgit-svn

git-svn: commit whole history of an existing git repository into an empty Subversion sub-directory


I've been working on some code locally on my computer, tracking modifications using git (no remote). That code is now to become a module in a larger project, the code base of which is stored in Subversion (so something like https://svnserver/svnroot/project/trunk/module_x), so I thought I could use git-svn to manage the Subversion repository as a remote. I remember doing that before for another project but could not find the modus operandi (changed computers in-between).

Here is what I tried:

cd ~/mygitrepo/
git svn init https://svnserver/svnroot/project/trunk/module_x
git svn fetch
git svn rebase

The last command yields the following error message:

Unable to determine upstream SVN information from working tree history

I read somewhere that it might be because the directory was empty in Subersion so I tried committing a dummy file to SVN separately then ran:

git svn fetch
    A   dummy.txt
r10744 = 89294ba713c6fed368f3b879c8dc7744b1015308 (refs/remotes/git-svn)

However, I cannot find the dummy.txt file in my git repo and both rebase and dcommit will continue to show the same error message. What did I do wrong?


Solution

  • The answer provided by Jan gives the rationale for the error I encountered and points to plain old git rebase --onto as the proper solution but lacks the actual commands.

    I initially proposed those commands as an edit to his answer but it was rejected, so here goes:

    git checkout -b svnrebase git-svn            # create a temporary branch
    git cherry-pick master~1                     # cherry pick the first  commit
    git rebase --onto svnrebase master~1 master  # rebase the 2nd through current commit
    git svn dcommit                              # finally commit the results to svn
    

    NOTE that master~1 must be changed to reference your first commit to the git master. Here, we suppose we have a git repo with just two commits.

    It is necessary to create a temporary branch and cherry-pick the first commit to master because rebase --onto only rebases the range of modifications made after master~1 (and the master~2 reference would not exist with just two commits).