最近接手一个非常老的项目,因为使用SVN进行控制,而现在大部分都已经使用Git进行版本控制,所以就想迁移到Git,Git的优点自然是不用在这里说了,必经是当前公认最好用的。
因为项目比较老,代码比较多,提交多达3w多次,同时svn还有几十个分支和标签,这些历史记录丢失将对今后追溯debug造成很多麻烦,所以关键是如何才能保留所有的这些提交记录、分支、标签。
为了实现正确的数据迁移,我们要对开发者信息,即提交作者的信息做一个映射,这就需要先生成一个用户对应关系的文件,格式如下:
JefferyWang = JefferyWang <jefferywang@example.com>
为了能够快速从svn内提取作者信息,可以使用下面的脚本,来快速提取在svn内有过提交的用户名,然后再做映射的处理,生成上面格式的文件即可:
svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2}' | sort -u
当然如果你们所有作者的邮箱后缀都是一样的,可以使用下面这段脚本:
svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2"@example.com>"}' | sort -u > authors.txt
如果你的svn仓库是标准的目录结构,即只包含 /trunk , /branches , tags 几个目录的结构,那么可以直接在运行命令的时候加上参数 --stdlayout 。
命令格式为 git svn clone --stdlayout --authors-file=authors.txt <svn-repo>/<project> <git-repo-name> ,下面是一个示例:
# git v1.x
git svn clone --stdlayout --authors-file=authors.txt http://svn.example.com/test_rep/demo_proj demo
# git v2.x
git svn clone --prefix="" --stdlayout --authors-file=authors.txt http://svn.example.com/test_rep/demo_proj demo
针对非标准的目录结构,我们分别做显式指定参数 --trunk , --branches , --tags 。
# git v1.x
git svn clone --trunk=/trunk --branches=/branches --branches=/bugfixes --tags=/tags --authors-file=authors.txt http://svn.example.com/test_rep/demo_proj demo
# git v2.x
git svn clone --prefix="" --trunk=/trunk --branches=/branches --branches=/bugfixes --tags=/tags --authors-file=authors.txt http://svn.example.com/test_rep/demo_proj demo
有些svn仓库可能非常大,而转换过程是个非常漫长的过程,这个也取决于机器性能。因此,如果你不在乎老的一些历史记录的话,那么你可以只保留部分提交历史,来加速转换的过程。
命令格式: git svn clone -r${REVNUMBER}:HEAD --stdlayout --authors-file=authors.txt <svn-repo>/<project> <git-repo-name>
git svn clone -r52733:HEAD --stdlayout --authors-file=authors.txt https://svn.waterstrong.com/demo demo
这里查看我们的仓库,就发现转换工作基本已经完毕了,如果你只关注trunk和master分支,那么可以不用在乎这一部分,直接跳到下一节即可。这一步主要是将分支和标签进行本地化。
git svn clone 操作并不会将svn的分支和标签导入到新的git仓库里面,并且在本地分支中也找不到svn的分支和标签。转换后,其实是把svn的分支和标签导入为git的远程分支和标签了,如下面示意图所示:
这个策略主要是为了svn和git双向同步服务的,但是我们切换为git后,应该大部分都会禁止在svn再进行提交,所以我们就需要对这些进行一下清理。
第一种方法:
Atlassian提供了一个工具 svn-migration-scripts.jar ,可以进行清理。
下载地址:svn-migration-scripts.jar 下载
使用方法:
java -Dfile.encoding=utf-8 -jar ~/svn-migration-scripts.jar clean-git
--force
第二种方法:
只需要执行两个命令:
# 标签本地化
for t in $(git for-each-ref --format='%(refname:short)' refs/remotes/tags); do git tag ${t/tags\//} $t && git branch -D -r $t; done
# 分支本地化
for b in $(git for-each-ref --format='%(refname:short)' refs/remotes); do git branch $b refs/remotes/$b && git branch -D -r $b; done
# 标签本地化
for t in $(git for-each-ref --format='%(refname:short)' refs/remotes | grep "origin/tags"); do git tag ${t/origin\/tags\//} $t && git branch -D -r $t; done
# 分支本地化
for b in $(git for-each-ref --format='%(refname:short)' refs/remotes); do git branch ${b/origin\//} refs/remotes/$b && git branch -D -r $b; done
git remote add origin JefferyWang@github.com:test/demo.git
git push origin --all
git push origin --tags
原文 https://blog.wangjunfeng.com/post/svn2git/
版本管理概念:版本管理是软件配置管理的基础,它管理并保护开发者的软件资源;好处:可以保留我们的历史版本,在代码开发到一半的时候,不至于无故丢失,还可以查看BUG的来龙去脉。
Git和SVN都是版本管理系统,但是他们命令区别后面会简单进行一个对比,我们先从原理的角度分析,大家想想为什么我们代码管理为什么一般用git,原型图和高保真管理一般用SVN?
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!