GitLab与SVN同时使用

背景

将使用Git来进行研发,但是要定期同步到SVN上,所以需要进行协作。

实现

工具

将使用git-svn工具进行同步,命令git svn,其中此命令有很多用法,这里只说明常用的几个。

CentOS7中安装git-svn

1
yum install git-svn

解决错误信息:

1
2
3
4
5
6
$ git svn clone svn://domain/project
git: ‘svn’ is not a git-command. See ‘git –help’.

Did you mean one of these?
fsck
show

svn与git用户对照

在Subversion中每个提交都有用户名,并在提交信息中展示,如果想让已经提交的信息更好的映射到Git中,需要从Subversion中导出提交的用户到Git,作为映射关系。因为Git是以邮箱来作为标识,所以需要建立一个author文件(或者其他你喜欢的名字),格式为:svn作者 = 作者昵称<邮箱地址>,示例如下:

1
2
john = John<john@gmail.com>
mike = Mike<mike@gmail.com>

可以简单使用脚本获取SVN提交作者(之后按照上面格式进行编辑即可):

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

如果SVN提交者和GIT用户一样,或者对于此对照不是很CARE,则可以省略此步骤。

Checkout SVN到本地

git svn命令将SVN项目Checkout到本地:

1
git svn clone svn://domain/project --authors-file=author project

如果不需要从头到尾的记录的话,则可以直接通过-r参数来控制导出的版本数(从xxx版本到head版本):

1
git svn clone svn://domain/project --authors-file=author -r xxx:head

这里需要注明--no-metadata这个参数,此参数可说明不要SVN信息,比较适合在迁移的时候,而要共用的话,是需要这类信息。因为在Checkout下来时候,会针对SVN的提交做补丁,产生一个Git提交。

如果没有使用--no-metadata来进行clone的话,在进行git log时候,可以看到git和svn的提交的关联关系,即git-svn-id属性。如果没有git-svn-id这个属性,是无法将git的记录提交到SVN。

如果使用了--no-metadata的话,提交信息会变得更加简单且可读性更好,因为去掉了对应关系。

简单说,如果需要想SVN提交信息,不要这个参数,如果只是迁移SVN记录到GIT,那么使用此参数。

Git配置

配置Git远程地址及本地信息:

1
2
3
4
5
6
# 设置git的提交用户名和邮箱
# --global参数是全局设定,如果是想当前项目设置,那么去除这个参数
git config --global user.name youname
git config --global user.email email@email.com

git remote add origin http://git.code.com/url/project-x.git

SVN获取更新

需要不定期从SVN拉取更新记录,并同步到GIT上:

1
2
3
git svn fetch
git checkout master
git svn rebase

在这边通过检出master分支,然后对svn拉取的代码进行合并。当然,如果需要的话,可以在其他分支进行合并。之后用rebase将提交记录应用到分支上,构成线性提交记录。

提交到SVN

如果在feature分支进行开发,之后需要提交到SVN上,有两个做法:

  1. 保留feature分支的提交记录
  2. 压缩feature分支的提交记录,变成一个提交记录

保留提交记录

只需要rebase到svn的分支上,然后dcommit提交到svn服务器。

1
2
3
4
5
6
7
8
9
10
11
12
# update svn code
git svn fetch
git checkout master
git svn rebase

# rebase feature to master
git checkout feature
git rebase master
git checkout master
# merge feature
git merge feature
git svn dcommit

压缩提交

和上面区别就是,拉取feature之后,没有人在master上进行提交,直接使用merge进行fast-forward合并,然后提交到SVN服务器。

如果你在master上面进行提交,而有人也在SVN上进行提交,这时GIT无法进行fast-forward合并,只能进行merge三方合并,之后把之前提交变成一个提交,推送到SVN服务器。

1
2
3
4
git checkout master
git svn rebase
git merge feature
git svn dcommit

总结

很麻烦,趁早用GIT吧!!!

REF

Practical tips for using Git with large Subversion repositories
Git - 迁移到 Git
git与svn 共舞 | 东东东 陈煜东的博客