git-svn迁移
该文章记录并介绍一下将svn库迁移到git仓库的过程。
准备工作
需要准备的东西有:
-
SVN仓库
-
安装好git、svn、git-svn
-
创建一个新的git仓库以准备之后的迁移
迁移过程
将svn工程导出为git工程
要想将SVN工程导出为git工程,使用git svn clone的命令即可,不过在使用这条命令前,我们要注意一下几个参数:
--authors-file
要想让每次commit提交的记录信息更好地映射到git里面,需要在svn用户名到git用户名之间建一个映射关系,我们通过使用user.txt来建立映射关系:
tdreamhuang = tdreamhuang <tdreamhuang@tencent.com> test = test <test@tencent.com>
左边为svn库用户名称,右边则为git仓库用户名及用户邮箱。
以下命令可以在svn库下导出如上例子格式的user.text:
svn log --xml http://tc-svn.tencent.com/beowulf/beowulf_proj | grep author | sed 's#<author>##' | sed 's#</author>##' | sort -u | sed 's/.*/& = & <&@tencent.com>/' > user.txt
若git库和svn库的用户名不统一或有其他用途,可以使用命令,在svn库下只导出用户列表(svn库若没在本地则需checkout下来再导出),之后的git用户名和邮箱再自己填充:
svn log --xml | grep -P "^<author" | sort -u | perl -pe 's/<author>(.*?)<\/author>/$1 = /' > user.txt
--trunk、--tags、--branches
-
--trunk
参数指明了svn主分支所在目录,如果不指明默认是trunk目录,--tags
指明了svn的tag所在目录,--branches
参数指明了其他分支所在目录,如果不指明默认是branches目录。 -
这几个选项指定的都是相对路径,相对于
git svn clone
后面紧跟着的路径位置,所以不要在选项里制定诸如“http://”开头的相对路径 -
除了trunk之外,其他几个选项都可以重复指定,如果你的分支/标签分别在svn目录上的不同文件夹下,可以多次指定。
-
这几个主要在拉取代码时用来区分分支和tag,由于我自己拉取时单纯只拉取主分支,故并无涉及,有需要者可以看下这里:svn迁移到git仓库并保留commit历史记录
-r
这个参数则是指明拉取svn的哪些目录,如果有的仓库太大,如果拉取全部的记录可能需要很长的时间并且有很大的机率会失败,所以可以使用该参数缩小范围,以提高成功率和节约时间。
--no-metadata
用来阻止git svn包含某些svn附带的信息,使用了之后,仓库则无法将新commit提交到svn库上,即只能从svn库拉取代码而不能commit代码。
接下来我们就使用clone命令导出git库:
git svn clone http://scm-gy.tencent.com/xxxx --no-metadata --authors-file=user.txt -r2416349:HEAD
连接远程git仓库
拉取完代码之后,则可以连接远程git仓库了,命令如下:
git remote add origin git@test.company.com/some_group/projectname.git
然后将代码push到git仓库即可
git push --set-upstream origin master
后续svn库的拉取
如果说svn库上还是有更新,需要再同步到git仓库上时,可以在项目仓库里使用:
git svn rebase
将svn库的代码拉取下来并合并到项目中,再使用:
git push
将代码上传到远程库即可。
不过我在处理的时候,使用git svn rabase
失败了,并没有将svn库的代码拉下来,于是采用了另外一种方式:
git svn fetch git rebase --onto remotes/git-svn --root master git push
先将代码fetch下来,再自己rebase一次,最后再push。其中remotes/git-svn
是fetch下来的代码存放的位置,可以自己观察替换。
tips
如果svn代码库记录过多,clone过程时间太长想下次再接着拉,那么可以将其终止后下次使用git svn fetch
则可以继续拉取了,不用再重新clone重新开始。