首页 云效2020 代码管理 Git 指南 SVN 如何通过命令迁移为 Git

SVN 如何通过命令迁移为 Git

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 <alex@alibaba.com>
misha = misha <misha@alibaba.com>
loki = loki <loki@alibaba.com>

此时,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 git@codeup.xxxx.git

推送至远端 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

阿里云首页 云效2020 相关技术圈