0%

SVN迁移到GIT

背景

一个使用svn做版本控制的老业务需要迁移到git,原有业务和其他多个业务一同放在一个大的svn仓库中,本次仅需要迁移该业务。目标是迁移到git后保留历史的提交信息,不需要保留svn分支,也不需要保留svn标签。

网上查阅了一些资料后发现git官方已经提供了迁移教程

步骤

https://sourceforge.net/p/keepass/code/HEAD/tree/ 这个项目为例,迁移 trunkPlugins 仓库

安装git-svn

1
yum install git-svn

创建svn和git的用户映射关系

推荐的做法是先从svn的log中导出所有用户,然后再编辑每个用户到git的映射关系

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 先检出仓库
svn checkout https://svn.code.sf.net/p/keepass/code/trunk/Plugins keepass-code-plugins.svn

# 导出所有用户
svn log keepass-code-plugins.svn --xml | grep -P "^<author" | sort -u | perl -pe 's/<author>(.*?)<\/author>/$1 = /' > users.txt

# 根据导出的users.txt编辑每个用户的映射关系
# 原始文件
> cat users.txt
bill-rubin =
eyebex =
# 映射后
> cat users.txt
bill-rubin = test <test@test.com>
eyebex = test2 <test2@test.com>

导入git

1
git svn clone https://svn.code.sf.net/p/keepass/code/trunk/Plugins --authors-file=users.txt --no-metadata keepass-code-plugins.git

删除分支

1
git --git-dir=keepass-code-plugins.git/.git for-each-ref refs/remotes | cut -d / -f 3- | grep -v @ | while read branchname; do git --git-dir=keepass-code-plugins.git/.git branch "$branchname" "refs/remotes/$branchname"; git --git-dir=keepass-code-plugins.git/.git branch -r -d "$branchname"; git --git-dir=keepass-code-plugins.git/.git branch -d "$branchname" ; done

删除标签

1
git --git-dir=keepass-code-plugins.git/.git for-each-ref refs/remotes/tags | cut -d / -f 4- | grep -v @ | while read tagname; do git --git-dir=keepass-code-plugins.git/.git tag "$tagname" "tags/$tagname"; git --git-dir=keepass-code-plugins.git/.git branch -r -d "tags/$tagname"; git --git-dir=keepass-code-plugins.git/.git branch -d "tags/$tagname"; done

对比差异

1
diff -x '.git' -x '.svn' -r keepass-code-plugins.svn keepass-code-plugins.git

设置远端仓库

1
git --git-dir=keepass-code-plugins.git/.git remote add origin git@github.com:Sinute/keepass-code-plugins.git

推送到远端

1
git --git-dir=keepass-code-plugins.git/.git push -u origin master

其他注意事项

在git中空目录无法被追踪,如果svn仓库中存在空目录(比如log目录),需要视情况添加 .gitignore.gitkeep