Git-SVN迁移SVN仓库到Git


1. 建立SVN用户到Git用户的映射文件svnuser.txt:

1. 使用svn log命令得到SVN用户列表:

$ svn log --xml|grep "^<author"|sort -u|awk -F '<author>' '{print $2}'|awk -F '</author>' '{print $1}' > svnuser.txt

2. 然后再按标准格式完成映射:

  • 所有SVN用户都必须添加, 缺少会报错;
  • 邮箱可不定义;
  • VisualSVN Server用户必须定义邮箱
VisualSVN Server
hzn=hzn<hzn@qq.com>
mcf=mcf<mcf@qq.com>
sj=sj<sj@qq.com>
tyq=tyq<tyq@qq.com>
wxj=wxj<wxj@qq.com>
wbk=wbk<wbk@qq.com>
zbj=zbj<zbj@qq.com>

2. 使用git svn clone克隆一个包含了trunk、branches和tags的完整SVN代码仓库

  • 首次执行时会被提示输入SVN的用户名与密码
  • –authors-file: 表示SVN账号映射到Git账号的文件,所有的SVN提交者都要做映射;
  • –trunk: 表示主干所在目录,没有分支可忽略;
  • –branches: 表示分支所在目录,没有分支可忽略;
  • –tags: 表示标签所在目录,没有标签可忽略;
  • –no-metadata: 表示不导出SVN元数据;当想要将Git仓库中的提交镜像回原SVN仓库中时,需要保留元数据。
  • –no-minimize-url: 表示不尝试读取上级目录;
$ git svn clone svn://192.168.32.45/laravel --no-metadata --authors-file=svnuser.txt --trunk=trunk --branches=branch --tags=tag --no-minimize-url

3. 处理标签及分支

接下来我们需要处理SVN的标签及分支。直接执行git branch -a命令,我们会发现本地只有master一个分支,SVN的分支和标签都被当做了远程分支,【图片仅供参考】:

Git分支图

4. 合并分支, 暂时只处理主分支

# 合并master分支
# 如果master分支相对于svn有新的提交,则可能需要处理差异
$ git merge remotes/git-svn

# [可选]新增git-svn分支,仅用于保存svn记录,git不能修改
git checkout -b git-svn remotes/git-svn

# [可选]查看日志
$ git log

5. 连接远程库, 提交代码

远程仓库尽量保持没有提交记录, 否则可能会出错

# 连接远程仓库
$ git remote add origin https://git.example.com/moxuandi/laravel.git

# 推送代码(以下两条命令等效)
$ git push --set-upstream origin master
$ git push -u origin master

# [扩展]推送所有分支
$ git push origin --all

# [扩展]推送所有标签
$ git push origin --tags

6. 上次迁移后, svn有新的提交记录, 再次迁移:

# 重新拉取svn仓库
$ git svn clone svn://192.168.32.45/laravel --no-metadata --authors-file=svnuser.txt --trunk=trunk --branches=branch --tags=tag --no-minimize-url

# 更新svn记录[适用于上次拉取后,svn又有新提交]
$ git svn fatch

# 连接远程Git仓库(上次迁移过的仓库)
$ git remote add origin https://git.example.com/moxuandi/laravel.git

# 拉取远程Git仓库代码
$ git pull

# 合并到git的master分支
# 如果master分支相对于svn有新的提交,则可能需要处理差异
git merge remotes/git-svn

# 推送代码(以下两条命令等效)
$ git push --set-upstream origin master
$ git push -u origin master

# [扩展]推送所有分支
$ git push origin --all

# [扩展]推送所有标签
$ git push origin --tags