完美将工程从SVN迁移到Git仓库,并保留commit历史

本案例并不需要安装svn环境

导出SVN系统工程

首先,我们需要一台Linux系统的机器(或者虚拟机),并安装git-svn:

1
yum install git-svn

进入将要进行保存代码仓库的目录(例如:/home/mygit),创建users.txt文件,其作用是为了将svn中的提交作者和mygit中的作者进行关联映射。该文件结构类似于:

1
2
ZhangSan = Zhang San <[email protected]>
LiSi = Li Si <[email protected]>

注意:该文件可以先从使用svn命令从svn服务器将代码checkout下来,然后使用命令生成一个svn作者列表,进行修改,因本人项目参与人数不多,故使用手工编写。

安装完git-svn工具之后,使用git svn clone xxx命令从svn服务器clone项目:

1
git svn clone --stdlayout --no-metadata -A users.txt http://svn.xxx.com/programer temp-dir

这个命令会在temp-dir中新建一个Git repo,并从svn中拉取代码,其中–stdlayout参数表示该项目在svn中是标准的trunk/branches/tags目录结构,如果不是,那么需要使用 –trunk, branches, –tags参数,除了trunk,其它的均是复数形式,如:

1
git svn clone --no-metadata -A users.txt http://svn.xxx.com/programer --trunk=trunk temp-dir

如果项目中没有任何分支,连trunk也没有,则不需要任何参数,如

1
git svn clone --no-metadata -A users.txt http://svn.xxx.com/programer temp-dir

如果出现用户名没有找到,更新users.txt文件之后,然后

1
2
cd temp-dir
git svn fetch

完成后,git会将checkout svn的trunk 到本地master分支,其它的svn branch将会设为git remote, 可以查看所有的svn branch

1
git branch -r

为其它svn branch创建本地分支

1
git checkout -b local_branch_name remotes/branch_name

为其它svn tag创建tag

1
git tag tag_name remotes/tags/tag_name

将上面的git-svn仓库 clone到一个干净的git本地库中

1
2
3
4
cd ..
git clone temp-dir projectName
rm -rf temp-dir // 删除之前的git-svn库
cd projectName // 进入干净的git本地库中

于是之前的git-svn库就成了现在的git本地库的remote branch了,可以使用git branch查看本地分支有哪些。 再使用git checkout …对每一个分支再建立一次本地分支

1
git checkout -b local_branch origin/remote_branch

tag貌似不需要再重新建立了,可以使用git tag查看本地是否有tag。
最后,将干净的git本地库中将之前的remote删除.

1
git remote rm origin
将本地git库推送到远端

将本地的git库推送到远程中央仓库

1
2
git remote add origin http://${user}@bitbucket.xxx.com/....
git push -u origin master

推送所有的branch

1
git push origin --all

推送所有的tag

1
git push origin --tags