How do I migrate an SVN repository with history to a new Git repository?

前端 未结 30 2229
离开以前
离开以前 2020-11-22 02:51

I read the Git manual, FAQ, Git - SVN crash course, etc. and they all explain this and that, but nowhere can you find a simple instruction like:

SVN repository in: <

30条回答
  •  梦谈多话
    2020-11-22 03:36

    Create a users file (i.e. users.txt) for mapping SVN users to Git:

    user1 = First Last Name 
    user2 = First Last Name 
    ...
    

    You can use this one-liner to build a template from your existing SVN repository:

    svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > users.txt
    

    SVN will stop if it finds a missing SVN user not in the file. But after that you can update the file and pick-up where you left off.

    Now pull the SVN data from the repository:

    git svn clone --stdlayout --no-metadata --authors-file=users.txt svn://hostname/path dest_dir-tmp
    

    This command will create a new Git repository in dest_dir-tmp and start pulling the SVN repository. Note that the "--stdlayout" flag implies you have the common "trunk/, branches/, tags/" SVN layout. If your layout differs, become familiar with --tags, --branches, --trunk options (in general git svn help).

    All common protocols are allowed: svn://, http://, https://. The URL should target the base repository, something like http://svn.mycompany.com/myrepo/repository. The URL string must not include /trunk, /tag or /branches.

    Note that after executing this command it very often looks like the operation is "hanging/freezed", and it's quite normal that it can be stuck for a long time after initializing the new repository. Eventually you will then see log messages which indicates that it's migrating.

    Also note that if you omit the --no-metadata flag, Git will append information about the corresponding SVN revision to the commit message (i.e. git-svn-id: svn://svn.mycompany.com/myrepo/@ )

    If a user name is not found, update your users.txt file then:

    cd dest_dir-tmp
    git svn fetch
    

    You might have to repeat that last command several times, if you have a large project, until all of the Subversion commits have been fetched:

    git svn fetch
    

    When completed, Git will checkout the SVN trunk into a new branch. Any other branches are setup as remotes. You can view the other SVN branches with:

    git branch -r
    

    If you want to keep other remote branches in your repository, you want to create a local branch for each one manually. (Skip trunk/master.) If you don't do this, the branches won't get cloned in the final step.

    git checkout -b local_branch remote_branch
    # It's OK if local_branch and remote_branch are the same name
    

    Tags are imported as branches. You have to create a local branch, make a tag and delete the branch to have them as tags in Git. To do it with tag "v1":

    git checkout -b tag_v1 remotes/tags/v1
    git checkout master
    git tag v1 tag_v1
    git branch -D tag_v1
    

    Clone your GIT-SVN repository into a clean Git repository:

    git clone dest_dir-tmp dest_dir
    rm -rf dest_dir-tmp
    cd dest_dir
    

    The local branches that you created earlier from remote branches will only have been copied as remote branches into the new cloned repository. (Skip trunk/master.) For each branch you want to keep:

    git checkout -b local_branch origin/remote_branch
    

    Finally, remove the remote from your clean Git repository that points to the now deleted temporary repository:

    git remote rm origin
    

提交回复
热议问题