为什么现在大家都不用SVN了?
SVN (Subversion) 是一个曾经热门的集中式版本控制工具,然而 Git 作为分布式版本控制工具,近年来特别受欢迎,很多公司、开发人员开始使用 Git 来替代 SVN。
针对历史代码迁移的问题,最原始而直接的方法是把代码手动下载下来,然后手动创建 Git 仓库,再把代码 Push 上去,但是这样做会造成原 SVN 中的 Commit 纪录丢失。
如何在保留历史记录的情况下,让代码资产从 SVN 顺利的迁移至 Git 呢?本文基于git-svn(查看更多)为基础进行讲解。
建立 SVN 用户到 Git 用户的映射
在 SVN,每个提交者在主机上有一个用户名,记录于提交信息中,而 Git 使用作者名称和邮箱来标记用户。
如果想迁移前后保证 Commit 作者信息可追溯,需要建立从 SVN 用户到 Git 作者的映射关系,这需要建立一个叫做 userinfo.txt 的文件,利用 SVN 作者 = 作者昵称 <邮箱地址>的格式表示映射关系。
查看 SVN 用户
首先检出全部 SVN 用户列表:
svn log --xml | grep "^<author" | sort -u | \awk -F '<author>' '{print $2}' | awk -F '</author>' '{print $1}' > userinfo.txt
输出的 userinfo.txt 文件内容如下:
alex
misha
loki
描述映射关系
接着按以上格式描述映射关系:
alex = alex <[email protected]>
misha = misha <[email protected]>
loki = loki <[email protected]>
此时,userinfo.txt 就准备好了,接下来开始克隆 SVN 地址。
下载 SVN 代码库
操作之前,你需要了解 SVN 目录和 Git 的关系:
SVN目录
- /trunk:开发主线,相当于 Git 中的 Master 分支;
- /branches:支线副本,相当于 Git 中的其余分支;
- /tags:标签,与 Git中的标签一样;
下载 SVN 仓库
把上一步准备好的 userinfo.txt 拷贝到准备克隆 SVN 代码的目录下,然后执行git svn clone命令克隆一个 Git 版本库。
如果你的项目是完全按照 trunk,branches,tags 来管理的,只需使用–stdlayout进行范围指定,迁移的命令可以写作如下:
git svn clone ["SVN repo URL"] --prefix=svn/ --no-metadata --authors-file=userinfo.txt --stdlayout
如果是非标准格式的仓库,可以通过 --trunk,–branches 和 --tags 去指定:
git svn clone ["SVN repo URL"] --prefix=svn/ --no-metadata --authors-file=userinfo.txt --trunk=trunk --tags=tags --branches=branches
- 参数 –no-metadata 表示阻止 Git 导出 SVN 包含的一些无用信息;
- 参数 –authors-file 表示 SVN 用户映射到 Git 用户的说明文件;
- 参数 –trunk 表示指定 SVN 的 trunk 分支;
- 参数 –branches 表示指定 SVN 的支线分支;
- 参数 –tags 表示指定 SVN 的标签;
ignore 文件转换
如果 SVN 库使用 svn:ignore 属性,可以使用以下命令将其转换为 .gitignore 文件:
cd [下载后目录]
git svn show-ignore > .gitignore
git add .gitignore
git commit -m 'Convert svn:ignore properties to .gitignore.'
“ trunk”分支重命名为“ master”
转换后,您的主要开发分支将被命名为“ trunk”,即 SVN 中的开发分支。
可以使用以下命令将其重命名为 Git 标准的“ master”分支:
git branch -m trunk master
清理标签
git-svn使所有 SVN 标签变成了 Git 中非常短的分支,形式为“标签/名称”,因此需要将这些短分支转换为实际的 Git 标签或删除掉它们,转换为 Git 标签的命令如下:
git for-each-ref --format='%(refname)' refs/heads/tags | % { $_.Replace('refs/heads/tags/','') } | % { git tag $_ "refs/heads/tags/$_"; git branch -D "tags/$_" }
转换其他分支为本地 Git 分支
除了标签转换外,还可以把远端剩下的分支变成本地 Git 分支:
git for-each-ref --format='%(refname)' refs/remotes | % { $_.Replace('refs/remotes/','') } | % { git branch "$_" "refs/remotes/$_"; git branch -r -d "$_"; }
推送至 Git 服务器
VN 代码已经 clone 到本地了,接着需要 push 到 Codeup 的服务端。
创建一个空仓库
参见 创建第一个代码库
接着在下图①处获取 Git 库地址:
接下来就可以将本地的仓库 push 到远程地址,命令如下:
git remote add origin [email protected]
推送至远端 Git 仓库
git push origin --all
如果原来的 SVN 项目有 Tags 的话, git push -u origin –all 运行之后并不能让分支和标签都推送到远端。实际上,只提交了 branches ,并没有提交tags。此时,你需要执行一下git push –tags
git push -u origin --tags
使用 Git 仓库
更多使用说明参见快速上手
附录
Git 迁移相关材料参见:https://git-scm.com/book/en/v2/Git-and-Other-Systems-Migrating-to-Git
关于我们
了解更多关于云效DevOps的最新动态,可微信搜索关注【云效】公众号;
福利:公众号后台回复【Git】,可获得《Git 权威指南》的作者蒋鑫为你带来的【视频教学系列】Git操作全指南,为你深入浅出,带你走进神奇的 Git 世界的。
看完觉得对您有所帮助别忘记点赞、收藏和关注呦;
版权归原作者 云效DevOps平台 所有, 如有侵权,请联系我们删除。