如何将具有历史记录的SVN存储库迁移到新的Git存储库?


1509

我阅读了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

我不希望它那么简单,也不希望它是单个命令。但我确实希望它不会尝试解释任何内容-仅说明在此示例中应采取的步骤。


6
它变得越来越容易,我自己完成了它,并在SO jmoses.co/2014/03/21/moving-from-svn-to-git.html
约翰·摩西

请在下面使用Casey的答案,但是在运行“ svn clone ...”命令之前,请参见如何将额外的“ Visual SVN Server”行添加到user.txt文件中...此处:stackoverflow.com/questions/8971208/ …
MacGyver'2

1
另外,如果您在GitHub个人资料中选中了“将电子邮件设为不公开”选项,请使用它作为users.txt中的电子邮件地址进行匹配。yourgituser@users.noreply.github.com,这样您的真实电子邮件地址就不会显示在提交。
百战天龙

Answers:


529

魔法:

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

Git和SVN的操作非常不同。您需要学习Git,并且如果您想从SVN上游跟踪更改,则需要学习git-svn。该git-svn 主页有一个很好的例子部分

$ git svn --help

139
@Casey的答案更好地回答了原始问题。
道格·威尔逊

3
这会保留分支机构和所有内容吗?还是只是克隆树干?
Eildosa 2012年

7
@Eildosa:这只会克隆树干。参见Casey的答案。
sleske 2013年

3
@DougWilson,但我在这里看不到任何Casey的答案。以下是从“创建用户文件”开始的13位作者的答案吗?
Andrey Regentov '16

67
对于想知道这是“ Casey的答案”(在此附近的许多评论中引用)的任何人,就是这个(Casey将其昵称改为cmcginty)。
Stefan Monov

1559

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

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

您可以使用此单行代码从现有的SVN存储库中构建模板:

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

如果SVN在文件中找不到丢失的SVN用户,它将停止。但是之后,您可以更新文件并从上次中断的地方开始接听。

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

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

该命令将在中创建一个新的Git存储库,dest_dir-tmp并开始提取SVN存储库。请注意,“-stdlayout”标志表示您具有通用的“ trunk /,branchs /,tags /” SVN布局。如果您的布局不同,熟悉--tags--branches--trunk选项(一般git svn help)。

所有常用的协议允许:svn://http://https://。该URL应该以基本存储库为目标,例如http://svn.mycompany.com/myrepo/repository。该URL字符串必须包括/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

如果要在存储库中保留其他远程分支,则要为每个分支手动创建一个本地分支。(跳过中继/主节点。)如果不这样做,则分支将不会在最后一步中被克隆。

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

标签被导入为分支。您必须创建一个本地分支,创建一个标签并删除该分支,以使其成为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

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

git checkout -b local_branch origin/remote_branch

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

git remote rm origin

36
Eelke的这篇博客文章是上述答案的很好的交叉参考。blokspeed.net/blog/2010/09/conversioning-from-subversion-to-git
kgriffs

4
这是99%的令人敬畏的步骤,按照这些步骤操作,除分支机构外,我一切都按顺序进行:在最后一步之后,它们仅是远程的(因此当我执行命令git remote rm origin时就消失了)
Dirty Henry

4

8
对于Windows下的用户,我基于以下方法创建了一个PowerShell脚本:gist.github.com/Gimly/90df046dc38181bb18de
Gimly 2014年

5
警告具有悠久历史的大型仓库,此过程缓慢且冗长。我放弃了尝试迁移所有旧分支而只是迁移主干的尝试。
杰西2015年

195

将Subversion仓库干净地迁移到Git仓库。首先,您必须创建一个文件,将您的Subversion提交作者名称映射到Git提交者,例如~/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-svn通过安装从MacPorts 获得git-core +svn

如果您的Subversion信息库与所需的git信息库位于同一台计算机上,则可以将此语法用于init步骤,否则全部相同:

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

1
当我对另一个答案发表评论时,我不得不删除其中的空格=users.txt因为导入正在中止并且我得到了一个空的存储库。
塞巴斯蒂安·格里戈诺利

8
啊! 简单有效的解释。在我的情况下,file:///拒绝工作,只是我先使用svnserve.exe --daemon,然后再使用svn://localhost/home/user/repo
Daniel Reis

在运行Mountain Lion的Mac上,直到我进入Xcode并安装在“首选项”窗格的“下载”选项卡中找到的命令行工具,git svn才起作用。或者,我可以只安装在Apple开发人员站点上找到的OS X Mountain Lion命令行工具。
德鲁

3
就我而言,我不得不将文件转换authors.txtutf-8 without BOM
Silvan 2015年

这对我来说很棒!有一次,我的本地仓库,我用cmcginty的帖子开始在“克隆你的GIT-SVN仓库到一个干净的Git仓库:”我认为主要的原因,我喜欢@zoul的回答是是使用的git svn initgit svn config后来终于git svn fetch因为它更容易为了做到这一点,我不得不抓了好几次才正确。cmcginty的单行代码可 git svn clone同时执行所有三个操作,对我来说太混乱了。
mike

70

我使用了svn2git脚本,并且像一个吊饰一样工作。


4
问:这是否可以解决标记和分支名称中的空格(在svn中允许,在git中不允许)?
spazm 2011年


这对我来说失败了,并出现了一个问题: groups.google.com/forum / #!topic/msysgit/7MQVwRO-2N4- 另请参见:github.com/nirvdrum/svn2git/issues/50解决方案在这里: stackoverflow.com/questions / 3009738 /…
HDave

最好解释一下答案,否则我们会产生脚本小子。
Josh Habdas

如果您的分支都位于SVN的根中并且没有主干或标签,该怎么办?
卡尔

58

我建议您在尝试不断使用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存储库中,以简化协作。

首先创建一个空的远程仓库(也许在GitHub上):

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

然后,有选择地同步您的主分支,以便当两者都包含新内容时,拉取操作将自动将远程主服务器与本地主服务器合并:

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

之后,您可能有兴趣尝试使用我自己的git_remote_branch工具,该工具有助于处理远程分支:

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

最新版本的后续跟踪:“ git与git_remote_branch合作的时间


非常有用,这非常有效。我要补充一点,如果要同步到远程存储库,则需要采取最后一步。在git配置步骤之后,我需要git push origin master
mag382 2012年

31

有一个新的解决方案可以平稳地从Subversion迁移到Git(或同时使用):SubGit

我自己在做这个项目。我们在存储库中使用SubGit-我的一些队友使用Git和一些Subversion,到目前为止,它运行良好。

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

$ subgit install svn_repos
...
TRANSLATION SUCCESSFUL 

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

如果您的Subversion存储库包含多个项目,则将在svn_repos / git目录中创建多个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(例如,对于已经配置的构建工具)。

希望这可以帮助!


4
请注意,一次性导入(使用subgit import命令)似乎甚至不需要许可证。还包括该svn:ignore属性到.gitignore文件的准确翻译。
krlmlr

1
SubGit无法识别我的私钥,也无法识别我在命令行中设置的任何标志。文档非常差。这不是可行的选择git svn
pfnuesel

1
错误:“ svn_repos”不是有效的已配置位置;SubGit配置文件丢失。
乔恩·戴维斯

19

请参阅git-svn官方手册。特别是,在“基本示例”下查看:

跟踪并为整个Subversion管理的项目(包括主干,标签和分支完成)做出贡献:

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

您的克隆命令有效,上面的命令给了我空空的git repos。唯一的区别似乎是显式的“ -T干线”。
user1984717 '19


14

SubGit(与死亡蓝屏相对)

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

就是这样

+要从SVN更新,这是第一个命令创建的Git存储库。

subgit import  directory/path/Local.git.Repo

我使用了一种快速迁移到Git的方法来存储庞大的存储库。
当然你需要一些准备。
但是,您可能根本不会停止开发过程。

这是我的方式。

我的解决方案如下所示:

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

大型SVN存储库的迁移需要大量时间。
但是更新完成的迁移只需几秒钟。

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

脚步

1. 下载SubGit

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

假设我们是在Windows上完成的(移植到Linux并不容易)。
在SubGit的安装bin目录(subgit-2.XX \ bin)中,创建两个.bat文件。

迁移文件/命令的内容:

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

“开始”命令在此处是可选的(Windows)。它将看到启动时的错误,并在SubGit完成后保持打开外壳的状态。

您可以在此处添加类似于git-svn的其他参数。我仅使用--default-domain myCompanyDomain.com来修复SVN作者的电子邮件地址的域。
我具有标准的SVN信息库的结构(主干/分支/标签),“作者映射”没有问题。所以我什么也没做。

(如果要迁移诸如分支之类的标记,或者您的SVN具有多个分支/标记文件夹,则可以考虑使用更详细的SubGit 方法

提示1:使用--minimal-revision YourSvnRevNumber可以快速了解问题的解决方法(某种调试)。查看已解析的作者姓名或电子邮件特别有用。
或限制迁移历史深度。

提示2:迁移可能会被中断(Ctrl+ C)并通过运行下一个更新命令/文件来恢复。
我不建议对大型存储库执行此操作。我收到“内存不足Java + Windows异常”。

技巧3:最好为您的结果裸存储库创建一个副本。

用于更新的文件/命令的内容:

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

要获取上一个团队对Git存储库的提交,可以运行任意次。

警告!不要触摸您的裸仓库(例如创建分支)。
您将遇到下一个致命错误:

无法恢复的错误:不同步,无法同步...将Subversion修订翻译为Git提交...

3.运行第一个命令/文件。大型存储库将花费大量时间。我的不起眼的资料库需要30个小时。

就是这样
您可以随时通过运行第二个文件/命令从SVN更新Git存储库。在将您的开发团队转到Git之前。
只需几秒钟。



还有另一项有用的任务。

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

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

  1. 配置遥控器

跑:

$ 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 push origin'*:*'对于旧的Git版本)

如果得到以下信息:错误:无法生成git:没有这样的文件或目录 ...对我来说,完全重建我的存储库可以解决此错误(30小时)。您可以尝试下一个命令

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

或尝试重新安装Git对我无用)。或者,您可以根据所有标签创建分支并将其推送。或者,或者,或者...


10

后代

对于复杂的情况,Eric S. Raymond的回骨术是首选工具。除了SVN之外,它还通过该fast-export格式以及CVS支持许多其他版本控制系统。作者报告了EmacsFreeBSD等古代存储库的成功转换。

该工具显然旨在实现近乎完美的转换(例如将SVN的svn:ignore属性转换为.gitignore文件),甚至适用于历史悠久的困难存储库布局。在许多情况下,其他工具可能更易于使用。

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



8

您必须安装

git
git-svn

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

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

Subversion仅列出每次提交的用户名。Git的提交具有更丰富的数据,但最简单的是,提交作者需要列出名称和电子邮件。默认情况下,git-svn工具将仅在“作者”和“电子邮件”字段中列出SVN用户名。但是,只需一点点工作,您就可以创建所有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

这将抓取所有日志消息,提取用户名,消除任何重复的用户名,对用户名进行排序并将其放入“ 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中创建的authors-transform.txt文件),并将git存储库放置在主目录内的“〜/ temp”文件夹中。

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

如果您的svn仓库使用的是svn:ignore属性,则可以使用以下命令轻松将其转换为.gitignore文件:

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

4.将存储库推送到裸露的git存储库

首先,创建一个裸仓库,使其默认分支与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的标准“ master”分支:

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

6.清理分支和标签

git-svn使所有Subversions标签成为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开头的超长命令提供>辅助提示。



7

仅使用git,SVN和bash的扩展答案。它包括不使用Trunk / Branches / tags目录布局使用常规布局的SVN库的步骤(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

使用此authors文件创建一个文件,您可以在其中将svn用户名映射到开发人员使用git config属性user.name和属性设置的用户名和电子邮件user.email(请注意,像GitHub的服务只具有相匹配的电子邮件就足够了)。

然后git svn将svn仓库克隆到git仓库,并告诉它有关映射的信息:

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

这可能会花费非常长的时间,因为git svn会针对存在的每个标记或分支分别检出每个修订版。(请注意,SVN中的标签实际上只是分支,因此它们最终会在Git中结束)。您可以通过删除不需要的SVN中的旧标签和分支来加快此过程。

在同一网络或同一服务器上的服务器上运行它也可以真正加快此过程。此外,如果由于某种原因该过程被打断了您可以使用

git svn rebase --continue

在很多情况下,您已经在这里完成了。但是,如果您的SVN仓库具有非常规的布局,而您只是想在SVN中放置目录,则可以在git分支中放置一些额外的步骤。

最简单的是仅在服务器上制作一个遵循约定并使用的新SVN存储库 svn copy将目录放置在中继或分支中。当您上次尝试此操作时,如果目录始终位于存储库的根目录,则这可能是唯一的方法git svn只是拒绝执行签出操作。

您也可以使用git执行此操作。对于git svn clone仅使用要放入git分支的目录。

运行后

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

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


我会提出对本信息与此链接结合:sailmaker.co.uk/blog/2013/05/05/...
琼PS

7

我已经发布了一个分步指南(此处),将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 fetch直到完成没有错误

3)更新主分支

git svn rebase

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

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

如果您需要更多详细信息,请阅读我的帖子或询问我。


6

我们可以使用git svn clone如下命令。

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

上面的命令将从SVN提交创建authors文件。

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

创建SVN项目时,以上命令将为您提供第一个修订版本号。

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

上面的命令将在本地创建Git存储库。

问题是它不会将分支和标签转换为推。您将必须手动进行操作。例如下面的分支:

$ 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
$

现在将master,branch和tag推送到远程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实用程序消除了使用分支和标签的手动工作。

使用command安装它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命令的不错包装。

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




3

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

  1. 输入远程SVN URL作为“源路径/ URL”。
  2. 出现提示时输入您的凭据。
  3. 输入本地文件夹位置作为“目标路径”。
  4. 给它起个名字。
  5. 在高级选项中,从“创建本地存储库类型”的下拉列表中选择“ Git”。
  6. 您可以选择指定要从中进行克隆的修订。
  7. 打克隆。

在SourceTree中打开存储库,您还将看到提交消息也已迁移。

现在转到存储库->存储库设置,并添加新的远程存储库详细信息。如果需要,请删除SVN遥控器(我通过“编辑配置文件”选项进行了此操作。

准备好并自由编写代码后,将代码推送到新的远程仓库中。


谢谢您,超级轻松,快捷!
里卡德2014年

谢谢,这对我有用。我正在使用SourceTree和Stash。
VK_217

3

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

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

从SVN迁移到GitLab的步骤

设定

  • SVN托管在svn.domain.com.au
  • 可以通过以下方式访问SVN http(其他协议也可以使用)。
  • GitLab托管在git.domain.com.au
    • 使用名称空间创建一个组dev-team
    • 至少创建了一个用户帐户,并将其添加到组中,并且该帐户具有用于迁移的帐户的SSH密钥(使用测试ssh git@git.domain.com.au)。
    • 该项目favourite-projectdev-team名称空间中创建。
  • 该文件users.txt包含相关的用户详细信息(每行一个用户),格式为username = First Last <address@domain.com.au>,其中usernameSVN日志中提供的用户名。(有关详细信息,请参见“参考”部分的第一个链接,特别是Casey用户的回答)。

版本号

  • 颠覆版本1.6.17(r1128011)
  • git版本1.9.1
  • GitLab版本7.2.1 ff1633f
  • Ubuntu服务器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

而已!在GitLab Web UI中重新加载项目页面,您将看到现在列出的所有提交和文件。

笔记

  • 如果存在未知用户,该git svn clone命令将停止,在这种情况下,将更新users.txtcd favourite-projectgit svn fetch从停止位置继续执行。
  • 标准trunk- tags- branches需要布局SVN仓库。
  • 提供给该git svn clone命令的SVN URL 停止在紧靠上方的级别trunk/tags/并且branches/
  • git svn clone命令产生大量输出,其中包括顶部的一些警告。我忽略了警告。

尽管此链接可以回答问题,但最好在此处包括答案的基本部分,并提供链接以供参考。如果链接的页面发生更改,仅链接的答案可能会失效。
黑洞2015年

1
我不同意。链接的内容可能会更改,并且此处重复的内容将不会更新,因此可能已过时(实际上,我认为自从我最初发布此答案以来,它已经更改了)。指导原则只是说要为链接包含一些相关的上下文,而我确实做到了–实际问题是通过链接整体回答的。不需要或不需要在此处复制整个链接的资源。我为此被否决了吗?
leftclickben

2

另外,当尝试使用git-svn dcommits进行git时,git-stash命令是天赐的礼物。

典型过程:

  1. 设置git repo
  2. 在不同的文件上做一些工作
  3. 决定使用git检查一些工作
  4. 决定要 svn-dcommit
  5. 获取可怕的“无法提交带有脏索引的错误”错误。

解决方案(需要git 1.5.3+):

git stash; git svn dcommit ; git stash apply

2

这是一个没有依赖关系的简单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上(秘密是--follow-tags)。

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


2
我使用了这个脚本。经过一番周折和错误,它为我工作。请注意,为此需要Git 1.8.3+,因为--follow-tags仅在此后才受支持。
nrobey 2014年

2

我在Windows计算机上,做了一个小批量,只需调用即可将具有历史记录(但无分支)的SVN存储库转移到GIT存储库

transfer.bat http://svn.my.address/svn/myrepo/trunk https://git.my.address/orga/myrepo

也许任何人都可以使用它。它创建一个TMP文件夹,并用git签出SVN存储库,然后添加新的源并将其推送...,然后再次删除该文件夹。

@echo off 
SET FROM=%1 
SET TO=%2 
SET TMP=tmp_%random%

echo from:  %FROM% 
echo to:    %TO% 
echo tmp:   %TMP%

pause

git svn clone  --no-metadata --authors-file=users.txt %FROM% %TMP%  
cd %TMP% 
git remote add origin %TO% 
git push --set-upstream origin master


cd .. 
echo delete %TMP% ... 
pause

rmdir /s /q %TMP%

您仍然需要带有用户映射的users.txt,例如

User1 = User One <u.1@xxx.com>

这个答案帮助我顺利地将所有存储库移至BitBucket。
冈萨林格

很高兴听到。我只有Gitea的经验...但是以这种方式转移了~~ 40个仓库。
cljk

非常好!Thnx
b3wii

警告; 我遇到了糟糕的字符集问题。我意识到这确实为时已晚,但是花了我几个小时才能解决。请检查您生成的存储库中是否包含确切的(!)预期来源
cljk

1

我只是想对Git社区做出贡献。我写了一个简单的bash脚本,它可以自动完成整个导入过程。与其他迁移工具不同,此工具依赖于本机git而不是jGit。该工具还支持具有较大修订历史记录和/或较大blob的存储库。可通过github获得:

https://github.com/onepremise/SGMS

该脚本将以以下格式转换存储在SVN中的项目:

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

该方案也很受欢迎,也受到支持:

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

每个项目将通过项目名称进行同步:

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

如果您希望转换全部回购,请使用以下语法:

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

0

在Subversion中有效地使用Git是git-svn的简要介绍。对于现有的SVN存储库,git-svn使其非常简单。如果您要启动一个新的存储库,则首先创建一个空的SVN存储库,然后使用git-svn进行导入比在相反的方向上容易得多。创建一个新的Git存储库然后导入到SVN可以完成,但这有点痛苦,特别是如果您不熟悉Git并且希望保留提交历史记录。


0

下载适用于Windows的Ruby安装程序,并安装最新版本。将Ruby可执行文件添加到您的路径。

  • 安装svn2git
  • 开始菜单->所有程序-> Ruby->使用Ruby启动命令提示符
  • 然后输入“ gem install svn2git”并输入

    迁移Subversion存储库

  • 打开Ruby命令提示符,然后转到要迁移文件的目录

    然后svn2git http:// [域名 ] / svn / [存储库根目录]

  • 将项目迁移到Git可能需要几个小时,具体取决于项目代码的大小。

  • 这个主要步骤有助于创建Git存储库结构,如下所述。

    SVN(/ Project_components)中继-> Git主SVN(/ Project_components)分支-> Git分支SVN(/ Project_components)标签-> Git标签

创建远程存储库并推送更改。


0

GitHub有一个进口商。创建存储库后,可以通过其URL从现有存储库导入。如果适用,它将询问您的凭据,然后从那里开始。

在运行时,它将找到作者,您只需将其映射到GitHub上的用户即可。

我已经在几个存储库中使用过它,它非常准确,而且速度也快得多!大约有4000次提交的存储库花了10分钟,而我的朋友花了四天!



0

有多种方法可以实现此目标。我已经尝试了其中的一些,但发现仅在Windows OS上安装了git和svn即可真正工作。

先决条件:

  1. Windows上的git(我已经使用过这个)https://git-scm.com/
  2. svn安装了控制台工具(我用过svn svn)
  3. SVN存储库的转储文件。 svnadmin dump /path/to/repository > repo_name.svn_dump

实现最终目标的步骤(将具有历史记录的所有存储库移至git,首先移至本地git,然后移至远程)

  1. 在目录REPO_NAME_FOLDER中创建空存储库(使用控制台工具或tortoiseSVN) cd REPO_NAME_PARENT_FOLDER,将dumpfile.dump放入REPO_NAME_PARENT_FOLDER

  2. svnadmin load REPO_NAME_FOLDER < dumpfile.dump 等待此操作,可能会很长

  3. 此命令是静默的,因此打开第二个cmd窗口:svnserve -d -R --root REPO_NAME_FOLDER 为什么不只使用file:/// ......?Unable to open ... to URL:由于回答https://stackoverflow.com/a/6300968/4953065,导致下一个命令将失败并显示

  4. 建立新资料夹SOURCE_GIT_FOLDER

  5. cd SOURCE_GIT_FOLDER
  6. git svn clone svn:// localhost /等待此操作。

最后,我们得到了什么?

让我们检查我们的本地存储库:

git log

看到您以前的提交?如果是的话-好的

因此,现在您有了功能齐全的本地git存储库,其中包含您的源代码和旧的svn历史记录。现在,如果要将其移动到某些服务器,请使用以下命令:

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

就我而言,我不需要标签命令,因为我的仓库没有标签。

祝好运!


0

将svn子模块/文件夹'MyModule'转换为具有历史记录的git,没有标签或分支。

要保留svn忽略列表,请在步骤1之后使用以上注释

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.