我阅读了Git手册、常见问题解答、Git-SVN速成课程等,他们都解释了这一点和那一点,但你找不到像这样的简单说明:

SVN存储库位于:svn://myserver/path/to/svn/repos

Git存储库位于:git://myserver/path/to/git/repos

git-do-the-magic-svn-import-with-history \
svn://myserver/path/to/svn/repos \
git://myserver/path/to/git/repos

我不希望它这么简单,也不希望它是一个命令。但我确实希望它不要试图解释任何事情——只是说在这个例子中应该采取什么步骤。


当前回答

这里的几个答案涉及https://github.com/nirvdrum/svn2git,但对于大型存储库,这可能会很慢。我试过使用https://github.com/svn-all-fast-export/svn2git相反,它是一个同名的工具,但用于将KDE从SVN迁移到Git。

设置它的工作稍微多了一些,但当为我完成转换时,其他脚本花费了数小时的时间。

其他回答

我强烈推荐我刚刚发现的这一系列短片。作者将指导您完成基本操作,并展示一些更高级的用法。

对于GitLab用户,我在这里提出了我如何从SVN迁移的要点:

https://gist.github.com/leftclickben/322b7a3042cbe97ed2af

从SVN迁移到GitLab的步骤

安装程序

SVN位于SVN.domain.com.au。SVN可以通过http访问(其他协议也可以)。GitLab位于git.domain.com.au,并且:与命名空间开发团队一起创建一个组。至少创建一个用户帐户,将其添加到组中,并具有用于迁移的帐户的SSH密钥(使用SSH进行测试git@git.domain.com.au).项目收藏夹项目是在开发团队名称空间中创建的。文件users.txt包含相关的用户详细信息,每行一个用户,格式为username=First Last<address@domain.com.au>,其中username是SVN日志中给定的用户名。(有关详细信息,请参见参考资料部分的第一个链接,特别是用户Casey的回答)。

版本

subversion 1.6.17(r1128011)git版本1.9.1GitLab版本7.2.1 ff1633fUbuntu服务器14.04

命令

git svn clone --stdlayout --no-metadata -A users.txt http://svn.domain.com.au/svn/repository/favourite-project
cd favourite-project
git remote add gitlab git@git.domain.com.au:dev-team/favourite-project.git
git push --set-upstream gitlab master

就是这样!在GitLab web UI中重新加载项目页面,您将看到现在列出的所有提交和文件。

笔记

如果有未知用户,git-svnclone命令将停止,在这种情况下,update-users.txt、cd-f收藏夹项目和git-svnfetch将从停止的位置继续。SVN存储库的标准主干标记分支布局是必需的。给git-svnclone命令的SVN URL在trunk/、tags/和branches/的正上方停止。git-svn-clone命令产生大量输出,包括顶部的一些警告;我无视警告。

这里有一个简单的shell脚本,它没有依赖关系,可以将一个或多个SVN存储库转换为git并将其推送到GitHub。

https://gist.github.com/NathanSweet/7327535

在大约30行脚本中:使用git SVN克隆,从SVN::ignore财产创建一个.gitignore文件,推入一个裸git存储库,重命名SVN主干为master,将SVN标记转换为git标记,并将其推送到GitHub,同时保留标记。

我经历了很多痛苦才将十几个SVN存储库从Google Code迁移到GitHub。我使用Windows并没有帮助。Ruby在我的旧Debian盒子上摔坏了,让它在Windows上运行简直是个笑话。其他解决方案无法使用Cygwin路径。即使我得到了一些有用的东西,我也不知道如何让标签显示在GitHub上(秘诀是——关注标签)。

最后,我拼凑了两个简短而简单的脚本,上面链接了起来,效果很好。解决方案不需要比这更复杂!

首先,感谢@cmginty的回答。对我来说,这是一个很好的起点,我将在这里发布的很多内容都借鉴了它。然而,我正在移动的回购已经有多年的历史,这导致了信件回复后出现了一些问题(需要手动移动数百个分支和标签,稍后阅读更多内容)。

因此,经过数小时的搜索和反复尝试,我能够编写一个脚本,使我能够轻松地将几个项目从SVN转移到GIT,我决定在这里分享我的发现,以防其他人也站在我的立场上。

<tl;我们开始吧


首先,创建一个“作者”文件,将基本svn用户转换为更复杂的git用户。最简单的方法是使用命令从要移动的svn repo中提取所有用户。

svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > authors-transform.txt

这将生成一个名为authors-transform.txt的文件,其中包含对运行该文件的svn repo进行更改的每个用户的一行。

someuser = someuser <someuser>

更新以包括git的全名和电子邮件

someuser = Some User <someuser@somewhere.com>

现在使用authors文件启动克隆

git svn clone --stdlayout --no-metadata -r854:HEAD --authors-file=authors-transform.txt https://somesvnserver/somerepo/ temp

--stdlayout表示svn repo遵循标准/主干/分支/标签布局--no-metadata告诉git不要在每次git提交时标记与svn提交相关的元数据。如果这不是单向转换,请删除此标记-r854:HEAD仅从854修订版获取历史记录。这是我遇到的第一个障碍;我正在转换的回购在853版本中有一个“损坏”的提交,因此它不会克隆。使用此参数,您只能克隆部分历史记录。temp是要创建以初始化的目录的名称新的git回购

这一步骤可能需要一段时间,特别是在大型或旧回购协议中(我们的一个回购协议大约需要18小时)。您还可以使用-r开关只获取一个小的历史记录来查看克隆,然后再获取其余的历史记录。

移动到新目录

cd temp

如果只在克隆中提取了部分历史记录,则获取任何缺失的历史记录

git svn fetch

标记在克隆期间创建为分支。如果你只有几个,你可以一次转换一个。

git 1.0.0 origin/tags/1.0.0

然而,如果你有数百个标签,这是很乏味的,所以下面的脚本对我很有用。

for brname in `git branch -r | grep tags | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'`; do echo $brname; tname=${brname:5}; echo $tname; git tag $tname origin/tags/$tname; done

您还需要签出所有要保留的分支

git checkout -b branchname origin/branches/branchname

如果你也有很多分支,这个脚本可能会有所帮助

for brname in `git branch -r | grep -v master | grep -v HEAD | grep -v trunk | grep -v tags | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'`; do echo $brname; git checkout -b $brname origin/$brname; done

这将忽略主干分支,因为它已经作为主分支签出,并保存一个步骤,稍后删除重复的分支,以及忽略我们已经转换的/标记。

现在是查看新回购的好时机,并确保您有一个本地分支或标记,可以保存任何您想保留的内容,因为远程分支将在片刻后删除。

好的,现在让我们将我们签出的所有内容克隆到一个干净的repo(此处名为temp2)

cd ..
git clone temp temp2
cd temp2

现在,我们需要再次检查所有分支,然后再将它们推到最后的远程位置,所以请按照上面您最喜欢的方法操作。

如果您正在使用gitflow,您可以重命名工作分支以进行开发。

git checkout -b WORKING
git branch -m develop
git push origin --delete WORKING
git push origin -u develop

现在,如果一切看起来都很好,就可以将其推送到git存储库了

git remote set-url origin https://somebitbucketserver/somerepo.git
git push -u origin --all
git push origin --tags

我确实遇到了最后一个问题,那就是Control Freak最初阻止我推送我没有创建的标签,所以如果您的团队使用Control Freak,您可能需要禁用或调整初始推送的设置。

GitHub现在具有从SVN存储库导入的功能。但我从未尝试过。