且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

我如何重新连接一个svn仓库的git仓库?

更新时间:2023-11-30 14:34:04

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
    D
    
    commit 4df9f21346526c6505a954d8310637864710308d
    C
    git-svn-id: $SVN_URL .../trunk@3...
    
    commit 116a6760d3e278aa4d54f5bb22e531d30d731661
    B
    git-svn-id: $SVN_URL .../trunk@2...
    
    commit d8bb201c6fd55ea5e645f2d8a07248593d177910
    A
    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
        .git/svn
        (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.

相关阅读

推荐文章