SVN到Git的手工迁移(保留所有分支、Tag及提交记录)

转载自:http://www.meilongkui.com/archives/1965

对于实际的存量项目而言,从SVN迁移到Git时是必须保留分支、Tag及提交记录的,以下以Bitbucket为例总结某个实际SVN代码仓库迁移到Git代码仓库的全过程。

一、建立SVN用户到Git用户的映射文件userinfo.txt

根据官网的文档:

在Subversion中,每一个人提交时都需要在系统中有一个用户,它会被记录在提交信息内。如果想要将Subversion用户映射到一个更好的Git作者数据中,你需要一个Subversion用户到Git用户的映射。

我们可以在对应SVN管理的工程文件夹下,使用如下命令获取到某个文件夹下所有提交者的名字:

svn log --xml|grep "^<author"|sort -u|awk -F '<author>' '{print $2}'|awk -F '</author>' '{print $1}' > userinfo.txt

这会将SVN的提交技术输出为XML格式,然后提取出作者信息,再重定向到userinfo.txt文件中。请注意:
1、由于用到grep、sort、awk,因此在Windows环境中需要在bash中运行,如果没有的话先安装Git即可;
2、需要安装svn的命令号工具,如果没有的话需要安装下:
SVN命令行工具
得到的userinfo.txt文件只包含了提交者,形如:
导出SVN提交者
接下来需要按照如下的格式完成映射:
SVN与Git用户映射
博主注:

如果SVN仓库使用VisualSVN管理的话,用户列表中会包含一个名叫VisualSVN Server的用户,需要将此用户也添加到映射列表中,才能顺利通过,例如:
VisualSVN Server=VisualSVN<VisualSVN@xxx.com>

二、使用git svn clone克隆一个包含了trunk、branches和tags的完整SVN代码仓库

一个典型的SVN仓库(该项目代号为eisp-eipsc-parent)形如:
一个典型的SVN仓库
我们使用如下命令进行克隆(首次执行时会被提示输入SVN的用户名):

$ git svn clone http://197.*.*.*:*/eisp/EIPSC/code/ --no-metadata --authors-file=userinfo.txt --trunk=trunk --branches=branch --tags=tag --no-minimize-url eisp-eipsc-parent-to-git

其中:
最后的eisp-eipsc-parent-to-git表示clone到此文件夹中
参数–authors-file表示SVN账号映射到Git账号的文件,所有的SVN提交者都要做映射;
参数–trunk表示主干所在目录;
参数–branches表示分支所在目录;
参数–tags表示标签所在目录;
参数–no-metadata表示不导出SVN元数据;当想要将Git仓库中的提交镜像回原SVN仓库中时,需要保留元数据。
参数–no-minimize-url表示不尝试读取上级目录;
git svn clone
如果不使用–no-minimize-url,则可能会导致在clone时扫描不正确的路径(Using higer level of URL):
不使用–no-minimize-url时Git默认会搜索上级目录
请注意,该–authors-file文件中必须包括SVN工程所涉及所有提交者的信息,如果缺少会报错(请注意,git svn执行时会将所有历史branch找到,即使该branch已经被删除,这些被删除分支中可能还有别的提交者,因此可能会报错,需要在遇到错误时再添加):
userinfo.txt中必须包含所有提交者的映射信息
当保留所有分支和提交记录时,git svn clone可能需要执行很久(This may take a while on large repositories),执行成功后形如:
git svn clone执行完成
此时可以看到master分支中的提交记录被完整保留了:
SVN中的原提交记录

三、处理标签及分支

接下来我们需要处理SVN的标签及分支。直接执行git branch -a命令,我们会发现本地只有master一个分支,SVN的分支和标签都被当做了远程分支:
本地只有一个master分支
执行git show-ref可以看到所有的引用:
git show-ref
首先,处理标签,创建本地标签并删除对应的远程分支:

git for-each-ref refs/remotes/origin/tags |cut -d / -f 5-|grep -v @| while read tagname; do git tag "$tagname" "origin/tags/$tagname"; done
git for-each-ref refs/remotes/origin/tags |cut -d / -f 5-|grep -v @| while read tagname; do git branch -r -d "origin/tags/$tagname"; done

处理标签
然后,在本地针对每一个远程分支创建对应的本地跟踪分支:

git for-each-ref refs/remotes/origin/ |cut -d / -f 4-|grep -v @| while read branchname; do git branch "$branchname" "refs/remotes/origin/$branchname"; done
git for-each-ref refs/remotes/origin/ |cut -d / -f 4-|grep -v @| while read branchname; do git branch -r -D "origin/$branchname"; done

处理分支
根据官方文档的描述,git svn会创建一个名为trunk的额外分支,它对应于Subversion的默认分支,然而trunk引用和master指向同一个位置。鉴于在Git中master最为常用,因此我们可以移除额外的分支:
删除无用的trunk分支
此时,可以观察到分支结构正常了:
正确的分支

四、移除在SVN中已经被删除的分支

在git svn命令执行的过程中,已经在SVN中被删除的分支也会被fetch到。例如,如下的提交对应的SVN分支实际早就被删掉了,可以看到提交记录是空的:
在SVN中已被删除的分支也被GIT还原了
我们可以利用如下的命令分别列出Git分支和SVN中的实际分支:
分别列出GIT和SVN的分支
然后使用diff命令找出不在SVN中的分支,然后将其删除:
删除已从SVN中删除发分支
这时再次观察分支接口,已经与SVN一致:
正确的分支

六、添加Git远程仓库地址

配置Git的username和email,并配置仓库的远程地址(需要在Bitbucket中先创建对应的Repository):

git config --global user.name ***
git config --global user.email ***
git remote add origin http://******/******.git
或
git remote set-url origin http://******/******.git

七、Push

将所有分支与标签推送到远程仓库:

git push origin --all
git push origin --tags

这样,我们就可以在Bitbucket中看到原SVN仓库相关的所有分支:
Bitbucket中可以看到原SVN仓库的所有分支
标签:
Bitbucket中可以看到原SVN仓库的所有标签
及提交记录:
Bitbucket中可以看到原SVN仓库的所有提交记录


参考文档:

1、https://git-scm.com/book/zh/v2/Git-%E4%B8%8E%E5%85%B6%E4%BB%96%E7%B3%BB%E7%BB%9F-%E8%BF%81%E7%A7%BB%E5%88%B0-Git,官方迁移文档;
2、https://blog.csdn.net/ouyang_peng/article/details/80372805
3、https://stackoverflow.com/questions/5914681/git-svn-bulk-removing-orphaned-remote-branches/7209462#7209462

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Git代码迁移SVN是一个复杂的过程,需要一定的技术知识和操作。下面是一个完整的详细教程,以帮助您进行Git代码到SVN迁移: 1. 准备工作: - 确保您的系统上已安装GitSVN。您可以从官方网站下载并安装它们。 - 确保您有读取Git仓库和写入SVN仓库的权限。 2. 创建一个空的SVN仓库: - 使用SVN创建一个新的空仓库,用于存储迁移后的代码和历史记录。 3. 克隆Git仓库: - 在本地选择一个目录,使用以下命令克隆Git仓库: ``` git clone <Git仓库URL> ``` 4. 配置Git-svn: - 在克隆的Git仓库目录中,运行以下命令来配置Git-svn: ``` git svn init <SVN仓库URL> --prefix=svn/ --no-metadata ``` - `<SVN仓库URL>` 是目标SVN仓库的URL。 - `--prefix=svn/` 参数将创建的SVN分支和标签的前缀设置为 "svn/"。 5. 迁移代码和提交记录: - 使用以下命令将Git提交记录迁移SVN: ``` git svn fetch ``` - 该命令会将所有Git提交记录逐一导入到SVN仓库中。 6. 提交SVN仓库: - 进入新创建的SVN仓库目录,使用以下命令提交SVN仓库: ``` svn add --force . svn commit -m "Initial import from Git" ``` 7. 验证迁移结果: - 检查SVN仓库中的代码和提交记录,确保迁移成功。 请注意,由于GitSVN之间存在一些概念和功能上的差异,一些高级特性(如分支、标签和Git特有的元数据)可能无法完全迁移。在进行迁移之前,请充分测试,并确保备份重要的数据。 此外,这只是一个基本的示例教程,实际迁移的复杂性取决于您的项目和仓库结构。如果您有特定的要求或遇到了问题,请提供更多关于您的项目和环境的信息,以便我能够提供更准确的建议。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值