写点什么

从 SVN 完美迁移到 Git,我只用了 5 分钟

作者:阿里云云效
  • 2022 年 5 月 18 日
  • 本文字数:1975 字

    阅读完需:约 6 分钟

从SVN完美迁移到Git,我只用了5分钟

为什么现在大家都不用 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 文件内容如下:

alexmishaloki
复制代码


描述映射关系


接着按以上格式描述映射关系:

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 > .gitignoregit add .gitignoregit 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


关于我们


了解更多关于云效 DevOps 的最新动态,可微信搜索关注【云效】公众号;


福利:公众号后台回复【Git】,可获得《Git 权威指南》的作者蒋鑫为你带来的【视频教学系列】Git 操作全指南,为你深入浅出,带你走进神奇的 Git 世界的。


看完觉得对您有所帮助别忘记点赞、收藏和关注呦;



发布于: 刚刚阅读数: 6
用户头像

云效,云原生时代一站式BizDevOps平台 2021.11.05 加入

云效,云原生时代一站式BizDevOps平台,支持公共云、专有云和混合云多种部署形态,通过云原生新技术和研发新模式,助力创新创业和数字化转型企业快速实现研发敏捷和组织敏捷,打造“双敏”组织,实现 10 倍效能提升

评论

发布
暂无评论
从SVN完美迁移到Git,我只用了5分钟_git_阿里云云效_InfoQ写作社区