如何将历史SVN仓库迁移到新的Git仓库?

我阅读了Git手册,FAQ,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 

我不指望它那么简单,我也不指望它是一个单一的命令。 但是,我希望不要试图解释任何事情 – 只是说明在这个例子中要采取什么措施。

魔法:

 $ git svn clone http://svn/repo/here/trunk 

Git和SVN的运行方式非常不同。 你需要学习Git,如果你想跟踪SVN上游的变化,你需要学习git-svngit-svn手册页有一个很好的示例部分:

 $ git svn --help 

创build一个用户文件(即users.txt )将SVN用户映射到Git:

 user1 = First Last Name <email@address.com> user2 = First Last Name <email@address.com> ... 

您可以使用这一行代码从现有的SVN存储库构build模板:

 svn log --xml | grep "<author>" | sort -u | perl -pe 's/.*>(.*?)<.*/$1 = /' | tee users.txt 

如果发现缺lessSVN用户不在文件中,SVN将停止。 但在此之后,您可以更新文件和提取您离开的地方。

现在从存储库中取出SVN数据:

 git svn clone --stdlayout --no-metadata --authors-file=users.txt svn://hostname/path dest_dir-tmp 

这个命令将在dest_dir-tmp创build一个新的Git仓库,并开始提取SVN仓库。 请注意,“–stdlayout”标志意味着您有共同的“trunk /,branches /,tags /”SVN布局。 如果你的布局不同,熟悉--tags ,– --branches ,– --branches选项(一般git svn help )。

所有常见的协议都是允许的: svn://http://https:// 。 该url应该以http://svn.mycompany.com/myrepo/repository为目标; 。 那一定不能包含/trunk/tag/branches

请注意,在执行这个命令之后,它经常看起来像是“挂起/冻结”操作,并且在初始化新的存储库之后很长时间卡住是非常正常的。 最终你会看到日志消息,表明它正在迁移。

还要注意,如果你省略了--no-metadata标志,Git会在提交消息中附加关于相应SVN修订版本的信息(例如git-svn-id: svn://svn.mycompany.com/myrepo/<branchname/trunk>@<RevisionNumber> <Repository UUID>

如果找不到用户名,请更新您的users.txt文件,然后:

 cd dest_dir-tmp git svn fetch 

如果你有一个很大的项目,你可能需要多次重复上一个命令,直到所有的Subversion提交都被提取出来为止:

 git svn fetch 

完成后,Git会将SVN trunk检入到一个新的分支。 任何其他分支设置为遥控器。 您可以通过以下方式查看其他SVN分支:

 git branch -r 

如果你想在你的仓库中保存其他远程分支,你想为每一个分支手动创build一个本地分支。 (跳过主干/主)。如果你不这样做,分支将不会在最后一步克隆。

 git checkout -b local_branch remote_branch # It's OK if local_branch and remote_branch are the same name 

标签是作为分支导入的。 你必须创build一个本地分支,制作一个标签并删除分支,把它们作为Git中的标签。 用标签“v1”来做:

 git checkout -b tag_v1 remotes/tags/v1 git checkout master git tag v1 tag_v1 git branch -D tag_v1 

将你的GIT-SVN库克隆到一个干净的Git仓库中:

 git clone dest_dir-tmp dest_dir rm -rf dest_dir-tmp cd dest_dir 

您之前从远程分支创build的本地分支只会被作为远程分支复制到新克隆的存储库中。 (跳过中继线/主站。)对于每个要保留的分支:

 git checkout -b local_branch origin/remote_branch 

最后,从干净的Git存储库中删除指向现在已删除的临时存储库的远程文件:

 git remote rm origin 

干净地迁移你的Subversion版本库到一个Git版本库 。 首先你必须创build一个将你的Subversion提交作者名称映射到Git commiters的文件,比如~/authors.txt

 jmaddox = Jon Maddox <jon@gmail.com> bigpappa = Brian Biggs <bigpappa@gmail.com> 

然后,您可以将Subversion数据下载到Git存储库中:

 mkdir repo && cd repo git svn init http://subversion/repo --no-metadata git config svn.authorsfile ~/authors.txt git svn fetch 

如果你在Mac上,你可以通过安装git-core +svn从MacPorts获得git-svn git-core +svn

如果你的Subversion版本库和你想要的git版本库在同一台机器上,那么你可以在init步骤中使用这个语法,否则就是一样的:

 git svn init file:///home/user/repoName --no-metadata 

我用svn2git脚本,像一个魅力! https://github.com/nirvdrum/svn2git

我build议在尝试不断使用git-svn之前先熟悉Git,即将SVN保持为集中式回购并在本地使用Git。

但是,对于所有历史的简单移植,以下是几个简单的步骤:

初始化本地回购:

 mkdir project cd project git svn init http://svn.url 

标记您想要开始导入修订的距离:

 git svn fetch -r42 

(或者只是“git svn fetch”所有转速)

实际上从那时起取得一切:

 git svn rebase 

您可以使用Gitk检查导入的结果。 我不确定这是否适用于Windows,它适用于OSX和Linux:

 gitk 

当你在本地克隆你的SVN回购时,你可能想把它推到一个集中的Git回购协议,以便于协作。

首先创build你的空的远程回购(也许在GitHub ?):

 git remote add origin git@github.com:user/project-name.git 

然后,可以select同步你的主分支,这样当两者都包含新的东西时,拉动操作会自动地将远程主控与你的本地主控合并:

 git config branch.master.remote origin git config branch.master.merge refs/heads/master 

之后,你可能会有兴趣尝试我自己的git_remote_branch工具,它有助于处理远程分支:

第一个说明文章:“ Git远程分支机构 ”

最新版本的跟进:“ 与git_remote_branch合作的时间 ”

有一个新的解决scheme,可以顺利从Subversion迁移到Git(或同时使用):SubGit( http://subgit.com/ )。

我正在自己做这个项目。 我们在我们的仓库中使用SubGit – 我的一些队友使用Git和一些Subversion,到目前为止它工作得很好。

使用SubGit从Subversion迁移到Git,您需要运行:

 $ subgit install svn_repos ... TRANSLATION SUCCESSFUL 

之后,您将在svn_repos / .git中获得Git存储库,并可以克隆它,或者继续使用Subversion和这个新的Git存储库:SubGit将确保两者始终保持同步。

如果您的Subversion版本库包含多个项目,那么将在svn_repos / git目录中创build多个Git存储库。 要在运行之前自定义翻译,请执行以下操作:

 $ subgit configure svn_repos $ edit svn_repos/conf/subgit.conf (change mapping, add authors mapping, etc) $ subgit install svn_repos 

使用SubGit,您可以迁移到纯Git(而不是git-svn)并开始使用它,同时仍然保持Subversion,只要您需要它(例如,您已经configuration的构build工具)。

希望这可以帮助!

请参阅官方的git-svn手册页 。 特别要看“基本例子”:

跟踪和贡献整个Subversionpipe理的项目(包含一个主干,标签和分支):

 # Clone a repo (like git clone): git svn clone http://svn.foo.org/project -T trunk -b branches -t tags 

Pro Git 8.2解释它: http : //git-scm.com/book/en/Git-and-Other-Systems-Migrating-to-Git

SubGit (vs蓝屏死亡)

 subgit import --svn-url url://svn.serv/Bla/Bla directory/path/Local.git.Repo 

就是这样

+从SVN更新,由第一个命令创build的Git存储库。

 subgit import directory/path/Local.git.Repo 

我使用了一种方式来立即迁移到一个巨大的仓库Git。
当然你需要一些准备。
但是你可能根本就不停止开发过程。

这是我的方式。

我的解决scheme看起来像

  • 将SVN迁移到Git存储库
  • 团队切换前更新Git存储库

迁移需要大量的时间来build立一个大的SVN仓库。
但更新完成的迁移只需几秒钟。

当然,我正在使用SubGit ,妈妈。 git-svn让我死亡的蓝屏 。 只是不断。 而git-svn让我无聊,Git的“ 文件名太长 ”致命错误。

脚步

1. 下载SubGit

2.准备迁移和更新命令。

比方说,我们这样做的Windows(这是微不足道的移植到Linux)。
在SubGit的安装bin目录(subgit-2.XX \ bin)中,创build两个.bat文件。

用于迁移的文件/命令的内容:

 start subgit import --svn-url url://svn.serv/Bla/Bla directory/path/Local.git.Repo 

这里“启动”命令是可选的(Windows)。 它将允许在开始时看到错误,并在完成SubGit后打开一个shell。

你可以在这里添加类似于git-svn的其他参数 。 我只使用–default-domain myCompanyDomain.com来修复SVN作者的电子邮件地址的域名。
我有标准的SVN存储库结构(trunk / branches / tags),我们没有“作者映射”的麻烦。 所以我什么都不做了

(如果你想迁移像分支标签或你的SVN有多个分支/标签文件夹,你可能会考虑使用更详细的SubGit 方法 )

技巧1 :使用–minimal-revision YourSvnRevNumber快速查看事情如何(某种debugging)。 特别有用的是查看已解决的作者姓名或电子邮件。
或限制迁移历史深度。

提示2 :迁移可能会中断( Ctrl + C ),并通过运行下一个更新命令/文件来恢复。
我不build议这样做的大型仓库。 我收到了“内存不足Java + Windowsexception”。

提示3 :最好创build一个结果仓库的副本。

文件/更新命令的内容:

 start subgit import directory/path/Local.git.Repo 

当你想获得最后一个团队对你的Git仓库的提交时,你可以运行任何次数。

警告! 不要触摸你的仓库(例如创build分支)。
你会采取下一个致命的错误:

不可恢复的错误:不同步,不能同步…将Subversion版本翻译成Git提交…

3.运行第一个命令/文件。 这将需要很长的时间才能build立一个大的仓库。 我谦卑的资料库30个小时。

就是这样
你可以在任何时候通过运行第二个文件/命令来从SVN更新你的Git仓库。 在开发团队切换到Git之前。
这只需要几秒钟。



还有一个更有用的任务。

将您的本地Git存储库推送到远程Git存储库

这是你的情况吗? 我们继续。

  1. configuration您的遥控器

跑:

 $ git remote add origin url://your/repo.git 
  1. 准备初始发送你的巨大的本地Git仓库到远程仓库

默认情况下,你的Git不能发送大块。 致命的:远端意外挂断

让我们来运行它:

 git config --global http.postBuffer 1073741824 

524288000 – 500 MB 1073741824 – 1 GB等

修复您的本地证书麻烦 。 如果你的git-server使用破损的证书。

我已经禁用证书 。

另外你的Git服务器可能有一个请求数量限制需要纠正 。

  1. 将所有迁移推送到团队的远程Git存储库。

使用本地Git运行:

 git push origin --mirror 

(旧Git版本的git push origin'*:*'

如果你得到以下错误:不能产卵git:没有这样的文件或目录 …对我来说,我的存储库的完整重新创build解决了这个错误(30小时)。 你可以尝试下一个命令

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

或者尝试重新安装Git ( 对我无用 )。 或者你可以从你所有的标签中创build分支并推送它们。 或者,或者,或…

这个在atlassian网站上的指南是我find的最好的之一:

https://www.atlassian.com/git/migration

这个工具 – https://bitbucket.org/atlassian/svn-migration-scripts – 也是非常有用的生成您的authors.txt等。

reposurgeon

对于复杂的案例, 埃里克·雷蒙德 ( Eric S.Raymond)的补偿是首选工具。 除了SVN之外,它还通过fast-export格式支持许多其他版本控制系统,还支持CVS 。 作者报告说, Emacs和FreeBSD等古代仓库的成功转换。

该工具显然是针对近乎完美的转换 (例如将SVN的svn:ignore属性转换为.gitignore文件),即使对于历史悠久的困难存储库布局也是如此。 对于许多情况下,其他工具可能更容易使用。

在深入研究reposurgeon命令行的文档之前,请务必阅读一步一步完成转换过程的出色DVCS迁移指南 。

一个稍微扩展的答案只使用git,SVN和bash。 它包括SVN存储库的步骤,不使用传统的布局与trunk / branches / tags目录布局(SVN绝对没有执行这种布局)。

首先使用这个bash脚本来扫描你的SVN回购为不同的贡献者,并为映射文件生成一个模板:

 #!/usr/bin/env bash authors=$(svn log -q | grep -e '^r' | awk 'BEGIN { FS = "|" } ; { print $2 }' | sort | uniq) for author in ${authors}; do echo "${author} = NAME <USER@DOMAIN>"; done 

使用这个来创build一个authors文件,在这个文件中,你可以使用git config属性user.nameuser.email (注意,像GitHub这样的服务只有一个匹配的邮件就足够了),将svn用户名映射到用户名和电子邮件。

然后让git svn克隆svn仓库到一个git仓库,告诉它关于映射:

git svn clone --authors-file=authors --stdlayout svn://example.org/Folder/projectroot

这可能需要很长的时间,因为git svn将单独检查每个标签或分支存在的每个修订版本。 (请注意,SVN中的标签只是真正的分支,所以它们在Git中结束了)。 你可以通过删除SVN中不需要的旧标签和分支来加快速度。

在同一个networking的服务器上或在同一台服务器上运行这个function也可以加快速度。 此外,如果由于某种原因,这个过程被中断,你可以继续使用

git svn rebase --continue

在很多情况下,你在这里完成。 但是,如果你的SVN回购有一个非传统的布局,你只需要在SVN中有一个目录,你想要把一个git分支,你可以做一些额外的步骤。

最简单的方法是在你的服务器上创build一个新的SVN回购协议,并使用svn copy将你的目录放在trunk或branch中。 这可能是唯一的办法,如果你的目录是在回购的根本,当我最后一次尝试这个git svn只是拒绝做结帐。

你也可以使用git来做到这一点。 对于git svn clone只需使用你想放入git分支的目录即可。

运行后

 git branch --set-upstream master git-svn git svn rebase 

请注意,这需要Git 1.7或更高版本。

你必须安装

 git git-svn 

从这个链接复制http://john.albin.net/git/convert-subversion-to-git

1.检索所有Subversion提交者的列表

Subversion只列出每个提交的用户名。 Git的提交有更丰富的数据,但最简单的,提交作者需要列出名称和电子邮件。 默认情况下,git-svn工具将在作者和电子邮件字段中列出SVN用户名。 但是有了一点工作,你可以创build一个所有SVN用户的列表,以及他们相应的Git名字和邮件是什么。 这个列表可以被git-svn用来将普通的svn用户名转换成合适的Git提交者。

从本地Subversion签出的根目录运行以下命令:

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

这将抓住所有的日志消息,拔出用户名,消除任何重复的用户名,sorting用户名,并将其放置到“authors-transform.txt”文件。 现在编辑文件中的每一行。 例如,转换:

 jwilkins = jwilkins <jwilkins> 

进入这个:

 jwilkins = John Albin Wilkins <johnalbin@example.com> 

2.使用git-svn克隆Subversion版本库

 git svn clone [SVN repo URL] --no-metadata -A authors-transform.txt --stdlayout ~/temp 

这将执行标准的git-svn转换(使用您在步骤1中创build的authors-transform.txt文件),并将git存储库放置在主目录中的“〜/ temp”文件夹中。

3.将svn:ignore属性转换为.gitignore

如果你的svn repo使用svn:ignore属性,你可以使用下面的命令轻松地将它转换成.gitignore文件:

 cd ~/temp git svn show-ignore > .gitignore git add .gitignore git commit -m 'Convert svn:ignore properties to .gitignore.' 

4.将仓库推送到一个纯粹的git仓库

首先,创build一个裸仓库,并使其默认分支匹配svn的“trunk”分支名称。

 git init --bare ~/new-bare.git cd ~/new-bare.git git symbolic-ref HEAD refs/heads/trunk 

然后将临时存储库推送到新的裸存储库。

 cd ~/temp git remote add bare ~/new-bare.git git config remote.bare.push 'refs/remotes/*:refs/heads/*' git push bare 

您现在可以安全地删除〜/ temp存储库。

5.将“trunk”分支重命名为“master”

您的主要开发分支将被命名为“trunk”,它与Subversion中的名称相匹配。 你需要使用以下命令将其重命名为Git的标准“主”分支:

 cd ~/new-bare.git git branch -m trunk master 

清理分支和标签

git-svn将所有的Subversions标签都变成了“tags / name”forms的Git中非常短的分支。 您将要使用以下命令将所有这些分支转换为实际的Git标记:

 cd ~/new-bare.git git for-each-ref --format='%(refname)' refs/heads/tags | cut -d / -f 4 | while read ref do git tag "$ref" "refs/heads/tags/$ref"; git branch -D "tags/$ref"; done 

这一步将需要一些打字。 :-)但是,别担心, 你的Unix shell会提供一个以git for-each-ref开始的超长命令的次要提示符。

GitHub现在有一个从SVN仓库导入的function。 虽然我从来没有尝试过。

TortoiseGit这样做。 看到这个博客文章: http : //jimmykeen.net/articles/03-nov-2012/how-migrate-from-svn-to-git-windows-using-tortoise-clients

是的,我知道用链接回答并不出色,但这是一个解决scheme,呃?

我们可以像下面一样使用git svn clone命令。

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

以上命令将从SVN提交创build作者文件。

  • svn log --stop-on-copy <SVN_URL>

当你的SVN项目被创build时,上面的命令会给你第一个修订号。

  • git svn clone -r<SVN_REV_NO>:HEAD --no-minimize-url --stdlayout --no-metadata --authors-file authors.txt <SVN_URL>

以上命令将在本地创buildGit存储库。

问题是,它不会转换分支和标签推。 你将不得不手动做。 例如下面的分支机构:

 $ git remote add origin https://github.com/pankaj0323/JDProjects.git $ git branch -a * master remotes/origin/MyDevBranch remotes/origin/tags/MyDevBranch-1.0 remotes/origin/trunk $$ git checkout -b MyDevBranch origin/MyDevBranch Branch MyDevBranch set up to track remote branch MyDevBranch from origin. Switched to a new branch 'MyDevBranch' $ git branch -a * MyDevBranch master remotes/origin/MyDevBranch remotes/origin/tags/MyDevBranch-1.0 remotes/origin/trunk $ 

对于标签:

 $git checkout origin/tags/MyDevBranch-1.0 Note: checking out 'origin/tags/MyDevBranch-1.0'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b new_branch_name HEAD is now at 3041d81... Creating a tag $ git branch -a * (detached from origin/tags/MyDevBranch-1.0) MyDevBranch master remotes/origin/MyDevBranch remotes/origin/tags/MyDevBranch-1.0 remotes/origin/trunk $ git tag -a MyDevBranch-1.0 -m "creating tag" $git tag MyDevBranch-1.0 $ 

现在推大师,分支机构和标签到远程git存储库。

 $ git push origin master MyDevBranch MyDevBranch-1.0 Counting objects: 14, done. Delta compression using up to 8 threads. Compressing objects: 100% (11/11), done. Writing objects: 100% (14/14), 2.28 KiB | 0 bytes/s, done. Total 14 (delta 3), reused 0 (delta 0) To https://github.com/pankaj0323/JDProjects.git * [new branch] master -> master * [new branch] MyDevBranch -> MyDevBranch * [new tag] MyDevBranch-1.0 -> MyDevBranch-1.0 $ 

svn2git实用程序

svn2git实用程序删除分支和标签的手动工作。

使用命令sudo gem install svn2git安装它。 之后运行下面的命令。

  • $ svn2git <SVN_URL> --authors authors.txt --revision <SVN_REV_NO>

现在您可以列出分支,标签并轻松推送。

 $ git remote add origin https://github.com/pankaj0323/JDProjects.git $ git branch -a MyDevBranch * master remotes/svn/MyDevBranch remotes/svn/trunk $ git tag MyDevBranch-1.0 $ git push origin master MyDevBranch MyDevBranch-1.0 

想象一下,你有20个分支和标签,显然svn2git会为你节省很多时间,这就是为什么我喜欢它比原生命令更好。 这是一个很好的包装本地git svn clone命令。

有关完整的示例,请参阅我的博客条目 。

我已经发布了一步一步的指导( 这里 )将svn转换为git,包括将svn标签转换为git标签和svn分支到git分支。

简短版本:

1)从特定版本号克隆svn。 (修订版号必须是您要迁移的最早的版本号)

 git svn clone --username=yourSvnUsername -T trunk_subdir -t tags_subdir -b branches_subdir -r aRevisionNumber svn_url gitreponame 

2)获取svn数据。 这一步,这是最花时间的一步。

 cd gitreponame git svn fetch 

重复git svn获取直到完成没有错误

3)更新主分支

 git svn rebase 

4)通过复制引用从svn分支创build本地分支

 cp .git/refs/remotes/origin/* .git/refs/heads/ 

5)将svn标签转换成git标签

 git for-each-ref refs/remotes/origin/tags | sed 's#^.*\([[:xdigit:]]\{40\}\).*refs/remotes/origin/tags/\(.*\)$#\2 \1#g' | while read p; do git tag -m "tag from svn" $p; done 

6)把仓库放在更好的地方,比如github

 git remotes add newrepo git@github.com:aUser/aProjectName.git git push newrepo refs/heads/* git push --tags newrepo 

如果你想要更多的细节,请阅读我的post或问我。

我强烈推荐我刚刚发现的这个简短的屏幕录像系列 。 作者引导您了解基本操作,并展示了一些更高级的用法。

如果您正在使用SourceTree,则可以直接从应用程序执行此操作。 转到文件 – >新build/克隆,然后执行以下操作:

  1. input远程SVN URL作为“源path/ URL”。
  2. 提示时input您的凭据。
  3. input本地文件夹位置作为“目标path”。
  4. 给它一个名字。
  5. 在高级选项中,从“Create local repository of type”下拉列表中select“Git”。
  6. 您可以select指定要从中克隆的修订。
  7. 命中克隆。

在SourceTree中打开回购,你会看到你的提交消息也被迁移了。

现在进入知识库 – >知识库设置,并添加新的远程回购细节。 如果你愿意的话,删除SVN远程(我通过“编辑configuration文件”选项来做到这一点。

当您准备好并自由编码时,将代码推送到新的远程回购。

另一方面,git-stash命令在尝试使用git-svn dcommits时是天赐良机。

一个典型的过程:

  1. 设置git回购
  2. 在不同的文件上做一些工作
  3. 决定使用git来检查一些工作
  4. 决定svn-dcommit
  5. 得到可怕的“不能提交一个脏索引”的错误。

解决scheme(需要git 1.5.3+):

 git stash; git svn dcommit ; git stash apply 

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

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

在大约30行脚本中:使用git SVN克隆,从SVN :: ignore属性创build一个.gitignore文件,推入一个纯粹的git仓库,将SVN主干重命名为master,将SVN标签转换为git标签,并将其推送到GitHub同时保留标签。

我经历了很多的痛苦,把十几个SVN仓库从Google Code移到GitHub。 这不利于我使用Windows。 Ruby在我以前的Debian盒子上被破坏,在Windows上工作是一个笑话。 其他解决scheme无法使用Cygwinpath。 即使我有一些工作,我也无法弄清楚如何让标签出现在GitHub上(秘密是–follow-tags)。

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

对于GitLab用户,我已经提出了一个关于如何从SVN迁移到这里的要点:

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

从SVN迁移到GitLab的步骤

build立

  • SVN托pipe在svn.domain.com.au
  • SVN可以通过http访问(其他协议应该可以)。
  • GitLab托pipe在git.domain.com.au和:
    • 使用名称空间dev-team创build一个组。
    • At least one user account is created, added to the group, and has an SSH key for the account being used for the migration (test using ssh git@git.domain.com.au ).
    • The project favourite-project is created in the dev-team namespace.
  • The file users.txt contains the relevant user details, one user per line, of the form username = First Last <address@domain.com.au> , where username is the username given in SVN logs. (See first link in References section for details, in particular answer by user Casey).

版本

  • subversion version 1.6.17 (r1128011)
  • git version 1.9.1
  • GitLab version 7.2.1 ff1633f
  • Ubuntu server 14.04

命令

 bash 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 

而已! Reload the project page in GitLab web UI and you will see all commits and files now listed.

笔记

  • If there are unknown users, the git svn clone command will stop, in which case, update users.txt , cd favourite-project and git svn fetch will continue from where it stopped.
  • The standard trunktagsbranches layout for SVN repository is required.
  • The SVN URL given to the git svn clone command stops at the level immediately above trunk/ , tags/ and branches/ .
  • The git svn clone command produces a lot of output, including some warnings at the top; I ignored the warnings.

I just wanted to add my contribution to the Git community. I wrote a simple bash script which automates the full import. Unlike other migration tools, this tool relies on native git instead of jGit. This tool also supports repositories with a large revision history and or large blobs. It's available via github:

https://github.com/onepremise/SGMS

This script will convert projects stored in SVN with the following format:

 /trunk /Project1 /Project2 /branches /Project1 /Project2 /tags /Project1 /Project2 

This scheme is also popular and supported as well:

 /Project1 /trunk /branches /tags /Project2 /trunk /branches /tags 

Each project will get synchronized over by project name:

 Ex: ./migration https://svnurl.com/basepath project1 

If you wish to convert the full repo over, use the following syntax:

 Ex: ./migration https://svnurl.com/basepath . 

Effectively using Git with Subversion is a gentle introduction to git-svn. For existing SVN repositories, git-svn makes this super easy. If you're starting a new repository, it's vastly easier to first create an empty SVN repository and then import using git-svn than it is going in the opposite direction. Creating a new Git repository then importing into SVN can be done, but it is a bit painful, especially if you're new to Git and hope to preserve the commit history.

Download the Ruby installer for Windows and install the latest version with it. Add Ruby executables to your path.

  • Install svn2git
  • Start menu -> All programs -> Ruby -> Start a command prompt with Ruby
  • Then type “gem install svn2git” and enter

    Migrate Subversion repository

  • Open a Ruby command prompt and go to the directory where the files are to be migrated

    Then svn2git http://[domain name]/svn/ [repository root]

  • It may take few hours to migrate the project to Git depends on the project code size.

  • This major step helps in creating the Git repository structure as mentioned below.

    SVN (/Project_components) trunk –> Git master SVN (/Project_components) branches –> Git branches SVN (/Project_components) tags –> Git tags

Create the remote repository and push the changes.

GitHub has an importer. Once you've created the repository, you can import from an existing repository, via its URL. It will ask for your credentials if applicable and go from there.

As it's running it will find authors, and you can simply map them to users on GitHub.

I have used it for a few repositories now, and it's pretty accurate and much faster too! It took 10 minutes for a repository with ~4000 commits, and after it took my friend four days!

Several answers here refer to https://github.com/nirvdrum/svn2git , but for large repositories this can be slow. I had a try using https://github.com/svn-all-fast-export/svn2git instead which is a tool with exactly the same name but was used to migrate KDE from SVN to Git.

Slightly more work to set it up but when done the conversion itself for me took minutes where the other script spent hours.

There are different methods to achieve this goal. I've tried some of them and found really working one with just git and svn installed on Windows OS.

Prerequisites:

  1. git on windows (I've used this one) https://git-scm.com/
  2. svn with console tools installed (I've used tortoise svn)
  3. Dump file of your SVN repository. svnadmin dump /path/to/repository > repo_name.svn_dump

Steps to achieve final goal (move all repository with history to a git, firstly local git, then remote)

  1. Create empty repository (using console tools or tortoiseSVN) in directory REPO_NAME_FOLDER cd REPO_NAME_PARENT_FOLDER , put dumpfile.dump into REPO_NAME_PARENT_FOLDER

  2. svnadmin load REPO_NAME_FOLDER < dumpfile.dump Wait for this operation, it may be long

  3. This command is silent, so open second cmd window : svnserve -d -R --root REPO_NAME_FOLDER Why not just use file:///…… ? Cause next command will fail with Unable to open ... to URL: , thanks to the answer https://stackoverflow.com/a/6300968/4953065

  4. Create new folder SOURCE_GIT_FOLDER

  5. cd SOURCE_GIT_FOLDER
  6. git svn clone svn://localhost/ Wait for this operation.

Finally, what do we got?

Lets check our Local repository :

 git log 

See your previous commits? If yes – okay

So now you have fully functional local git repository with your sources and old svn history. Now, if you want to move it to some server, use the following commands :

 git remote add origin https://fullurlpathtoyourrepo/reponame.git git push -u origin --all # pushes up the repo and its refs for the first time git push -u origin --tags # pushes up any tags 

In my case, I've dont need tags command cause my repo dont have tags.

祝你好运!

Converting svn submodule/folder 'MyModule' into git with history without tags nor branches.

To retain svn ignore list use the above comments after step 1

我使用以下脚本来阅读一个文本文件,其中包含我所有的SVN回购列表,并将其转换为GIT,然后使用git clone –bare将其转换为纯粹的git回购

  #!/bin/bash file="list.txt" while IFS= read -r repo_name do printf '%s\n' "$repo_name" sudo git svn clone --shared --preserve-empty-dirs --authors-file=users.txt file:///programs/svn/$repo_name sudo git clone --bare /programs/git/$repo_name $repo_name.git sudo chown -R www-data:www-data $repo_name.git sudo rm -rf $repo_name done <"$file" 

list.txt有格式

 repo1_name repo2_name 

而users.txt有格式

(no author) = Prince Rogers <prince.rogers.nelson@payesley.park.org>

www-data是Apache Web服务器用户,需要权限才能通过HTTP推送更改