背景
SVN和Git同样都是在特定时代下比较优秀的版本控制系统,但是随着时代的发展,SVN越来越不能满足多人开发的需求,尤其是在多种多样,天马星空的业务场景面前,SVN会显得力不从心,而Git也慢慢的成为趋势。
操作
生成作者文件:
因为我们知道,在SVN上提交和在Git上提交对应提交者的信息展示是不同的,SVN只会保存一个用户名,而Git会保存该用户的邮箱,所以我们迁移的第一步就要生成一个映射文件,将SVN上的用户名和其邮箱对应起来,就比如 molier = molier <[email protected]>
,转换的办法有很多,如果你团队里面的人不是很多的是时候,可以自己去提交记录中手动生成这样一个TXT文件
XXX = XXX <[email protected]>
XXX = XXX <[email protected]>
.
.
.
.
但是如果,多人开发人数很多的时候,手动转很累,我们就需要一个Atlassian的工具包 svn-migration-scripts.jar,通过命令拉取SVN仓库的用户并生成对应的开发者信息映射文件,需要Java运行时环境支持,大家可能还需要安装JDK:
java -jar svn-migration-scripts.jar authors https://svn.example.com > authors.txt
这样之后会在当前目录生成一个 authors.txt 文件
转换仓库
整体转换
- 标准的SVN文件布局:
如果SVN仓库使用标准的了/trunk, /branches和/tags的目录结构,就可在运行命令时加上参数–stdlayout,使用如下命令
git svn clone --stdlayout --authors-file=authors.txt <svn-repo>/<project> <克隆到文件夹的名字>
- 非标准的的SVN文件布局:
如果SVN仓库是非标准的目录布局,那就需要分别显示指定参数–trunk, --branches, --tags。
git svn clone --trunk=/trunk --branches=/branches --branches=/bugfixes --tags=/tags --authors-file=authors.txt <svn-repo>/<project> <克隆到文件夹的名字>
部分转换
如果仓库非常庞大的话可以选择部分转换,也就只转换指定提交之后的提交,可以试用如下代码
git svn clone -r123456:HEAD --stdlayout --authors-file=authors.txt <svn-repo> <克隆到文件夹的名字>
不过这里需要注意的是如果使用这种方式来转换那么一定要指定SVN的代码根部,而不能指定分支,因为SVN的提交编号都是按照时间顺序来往下依次排列,不同的分支也可能提交编号是连续的,所以如果只关心编号的话就不能再指定分支了。
以上三步中所用到的 authors.txt 即为上一步所生成的,作者 -> 作者 <作者邮箱> 的对应关系文件.
git svn 同步
最近接手的项目代码放在svn,但是svn推送分支的代价太高了,每个分支目录都是一次全拷贝,所以项目转用git进行版本管理。
最傻的方法是新建git分支,将svn的代码作为源代码重新提交,但是这种方法没办法获取到svn的commit记录,这对版本追踪是不可忍的。所以放弃。
第二种方式,是将svn的分支连同commit记录一起merge到git,然后再用git进行版本管理。
参考资料:
- https://www.cnblogs.com/czlovezmt/p/9834936.html
- http://blog.csdn.net/ouyang_peng/article/details/76220621
- https://www.cnblogs.com/jaspersong/p/8029567.html
- http://www.it1352.com/802059.html
- https://www.cnblogs.com/czlovezmt/p/9834936.html
- https://www.jianshu.com/p/a1a8fa32f49e
使用场景 :将已有的SVN项目迁移至git
场景一: 从旧SVN项目同步代码至新的git项目
注意:
该步骤只有第一次迁移的时候才需要做,一旦迁移成功,所有svn的代码都应该由git更新,不应该直接在svn上提交,否则版本库会乱
具体步骤
1、 在git 创建对应的project
2、 clone git项目
3、 在.git/config中添加svn-remote,创建命令如下。
[svn-remote "svn"]
url = http://svn.*****.com/***********/branches/release
fetch = :refs/remotes/git-svn-release
4、 第三步中创建了一个名为svn的git-svn同步分支,该分支为所有其他git分支连接SVN代码库的桥梁,只有当需要将代码同步至SVN时才会往该分支合代码。
5、 从空的svn远程库中做初始化fetch,并将其作为一个新分支checkout
git svn fetch svn
git checkout -b svn git-svn-release
6、git show-ref命令查看分支情况
到有个远程分支remotes/git-svn-release。
7、 假设我们所有的开发分支最后都要合到develop分支上,我们就用develop分支和同步分支做交互。
8、 checkout至develop分支,将svn分支merge进develop分支,这样SVN的代码库就原封不动连同日志一起在git中建立了起来。
git checkout develop
git merge svn --no-ff
git commit
场景二: 在已经使用git开发的情况下建立git到svn的同步机制
如果上述场景一已经做完,作为一个开发,我现在只能拉到develop分支,我如何建立起这么一套同步机制呢?
重做场景一中的前8步,这样使得我们本地有一个svn(和上面的并不是一个分支,没有联系),与之建立联系的是远程svn服务器上的git-svn分支
此时的develop分支和svn分支是两条从一个根节点出发的线,这个跟节点就是场景一中第一次将 svn merge入develop的这次提交。
虽然这两个分支最后当前的文件内容应该是相同的,但是git并不会这么认为,它会觉得这是两条截然不同的分支,为了能够让develop和svn建立起关系,需要再将develop和svn合并,把develop合入svn。
git checkout svn
git merge develop --no-ff
场景三,将改动提交到svn
已经建立git到svn的同步机制的情况下。
git checkout svn
git svn dcommit