How can I reconnect a git repository with a svn repository?

I used git svn to import an existing Subversion repo into git. I then pushed this to git repo on a git server. Over the last few months changes to the software have been made in both Subversion and git repositories. Unfortunately, my local copy with the links between svn and git has been deleted.

I've tried to recreate the local copy using git svn again, but when I do a pull from the git server it complains warning: no common conflicts and I end up merging two separate branches with the same commits at the start. Like this:

| \
E  D
|  |
C  C
|  |
B  B
|  |
A  A

How can I get it to treat the svn changes like they happened on a branch from the original repo?

| \
E  D
| /


By default git-svn stores mapping between SVN revisions and Git commits in commit messages. Do you see these git-svn-id lines for older commits in your original Git repository? Here I mean that Git repository hosted on the Git server and not that one you've fetched from SVN recently.

If so, you actually didn't loose any links and git-svn should be able to restore the necessary data from the history. Though due to some compatibility issues between different versions of git-svn this may be a bit tricky:

  1. Clone your original Git repository:

    $ git clone $GIT_SERVER repo
    $ cd repo
  2. Update git-svn configuration in .git/config:

    $ git config svn-remote.svn.url $SVN_URL
    $ git config svn-remote.svn.fetch trunk:refs/remotes/trunk
    $ git config svn-remote.svn.branches branches/*:refs/remotes/*
    $ git config svn-remote.svn.tags tags/*:refs/remotes/tags/*
  3. Now you have to update refs/remotes/* refs to the latest commits with git-svn-id line:

    $ git log --first-parent refs/heads/master
    commit d566edf5f77ae0a2f7418c40949757e75ef8e83c
    commit 4df9f21346526c6505a954d8310637864710308d
    git-svn-id: $SVN_URL .../trunk@3...
    commit 116a6760d3e278aa4d54f5bb22e531d30d731661
    git-svn-id: $SVN_URL .../trunk@2...
    commit d8bb201c6fd55ea5e645f2d8a07248593d177910
    git-svn-id: $SVN_URL .../trunk@1...

    As you can see commit D does not have git-svn-id line, but commit C has one and that line refers to trunk, so you have to update refs/remotes/trunk to commit C:

    $ git update-ref refs/remotes/trunk 4df9f21346526c6505a954d8310637864710308d
  4. If you have many branches and tags, repeat the same steps for them with respect to the mapping we've specified above:

    • branches/foo => refs/remotes/foo

    • tags/1.0 => refs/remotes/tags/1.0

  5. The final step is to restore the mapping in .git/svn directory:

    $ git svn fetch
    Migrating from a git-svn v1 layout...
    Data from a previous version of git-svn exists, but
        (required for this version (X.Y.Z) of git-svn) does not exist.
    Done migrating from a git-svn v1 layout
    Rebuilding .git/svn/refs/remotes/trunk/.rev_map.694389ff-b137-4359-84f9-4d1a25628e89...
    r1 = d8bb201c6fd55ea5e645f2d8a07248593d177910
    r2 = 116a6760d3e278aa4d54f5bb22e531d30d731661
    r3 = 4df9f21346526c6505a954d8310637864710308d
    Done rebuilding .git/svn/refs/remotes/trunk/.rev_map.694389ff-b137-4359-84f9-4d1a25628e89

The last command also fetches new revisions from SVN server. After the command is done you have a git-svn clone of Subversion repository. The history in this repository has diverged, so you have to synchronize changes between SVN and Git repositories as usually:

$ git svn rebase
$ git svn dcommit

Hope that helps.

First, I'd check the output of the git svn info command. Do you see some strange things there?

Second, the thing is that it is not a good idea to use git svn with a secondary git repository other than your local one.

The reason is that after each git svn dcommit git automatically rewrites all the commits you made previously: first it commits them back to svn and then adds the svn revision number for the commit (in a unique identifier called git-svn-id).

It should be something like this in a repository where you made a new dcommit:

$ git log -1
commit 1234abc...
Author: ...
Date:   ...

Some commit message

git-svn-id: http://your.svn.repo/svn/trunk@10 1234abc

About the details, here is a section from the ProGit book.

The error message you wrote is probably warning: no common commits (not conflicts as you wrote in the question), and my impression is that git did not pushed these metadata into the remote repo.

I think you can raise this SVN link from the dead, but be careful, make it on a separate clone of the repo, and read the documentation carefully about what metadata it needs. In git, you can do quite a lot of things with the plumbing tools, take a look on them.

Btw cannot you simply clone the remote git repo and use that?

Hope this helps something, or at least give you a few ideas where you can start looking for a solution.

From the commit graph

| \
E   D
|   |
C1  C2
|   |
B1  B2
|   |
A1  A2

use the following command

git checkout <SHA1-B1>
git checkout -b new
git cherry-pick <SHA1-C2> <SHA1-D>
git checkout <SHA1-F>
git checkout -b position_f
git merge new

Done. Anyway, I haven't try it yet. Backup your repository at first.

The simplest solution is to push your local git-svn branches to your git server, like this:

git push <git-server> <branch-name>:<branch-name>

It will override git-server branches with your local ones.

Do that only if you are certain that git-svn branches have all the commits that git server has.

How about this:

  • Take a backup!
  • Re-import the svn history into git
  • Get your old branch and the new branch into the same repo
  • Rewind your branch to the commit before F
  • Rebase all the changes in your branch since your C on top of the newly-svn-imported C
  • Re-attempt the merge

If this doesn't work, you could try Git replace, but it might be a bad idea.

Need Your Help

JmDNS service discovery in client-server

java network-programming client-server service-discovery jmdns

I'm trying to enable service discovery in my client-server application using JmDNS. I fully understand service registry on the server side, with code that resembles this:

Prevent Use of the Back Button (in IE)

javascript internet-explorer back-button

So the SMEs at my current place of employment want to try and disable the back button for certain pages. We have a page where the user makes some selections and submits them to be processed. In s...