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

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


魔法:

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

Git和SVN的操作非常不同。你需要学习Git,如果你想跟踪SVN上游的变化,你需要学习Git-SVN。git-svn主页有一个很好的示例部分:

$ git svn --help

将Subversion存储库干净地迁移到Git存储库。首先,您必须创建一个将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。

如果您的subversion存储库与所需的git存储库位于同一台机器上,那么您可以在init步骤中使用此语法,否则都一样:

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

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

跟踪和贡献整个Subversion管理的项目(完成具有主干、标签和分支):

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

我建议在尝试经常使用Git-svn之前,先熟悉Git,即保持svn作为集中存储库并在本地使用Git。

然而,对于具有所有历史记录的简单迁移,以下是几个简单步骤:

初始化本地回购:

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

标记要开始导入修订的时间:

git svn fetch -r42

(或仅对所有版本使用“gitsvn-fetch”)

事实上,从那时起,获取一切:

git svn rebase

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

gitk

当您在本地克隆了SVN repo后,您可能希望将其推送到集中的Git repo,以便于协作。

首先创建空的远程存储库(可能在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协作的时间”


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


另一方面,当尝试使用git-svn-dcommits进行git时,git-stash命令是一个天赐的选择。

典型流程:

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

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

git stash; git svn dcommit ; git stash apply

有效地将Git与Subversion结合使用是对Git-svn的简单介绍。对于现有的SVN存储库,git-SVN使其变得非常简单。如果您正在启动一个新的存储库,那么首先创建一个空的SVN存储库,然后使用git-SVN导入要比相反的方向容易得多。创建一个新的Git存储库,然后导入到SVN中是可以做到的,但这有点痛苦,特别是如果您是Git新手,希望保留提交历史记录。


创建一个用户文件(即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/ {gsub(/ /, "", $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

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

允许使用所有通用协议:svn://、http://、https://。URL应该以基本存储库为目标,例如http://svn.mycompany.com/myrepo/repository.URL字符串不能包含/trank、/tag或/branches。

请注意,在执行此命令后,操作通常看起来像是“挂起/冻结”,并且在初始化新存储库后,它可能会被卡住很长一段时间,这很正常。最终,您将看到指示它正在迁移的日志消息。

还要注意,如果省略--no元数据标志,Git将在提交消息中附加有关相应SVN修订的信息(即Git-SVN-id:svn://svn.mycompany.com/myrepo/<branchname/trank>@<RevisionNumber><RepositoryUUID>)

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

cd dest_dir-tmp
git svn fetch

如果您有一个大型项目,则可能需要重复最后一个命令几次,直到获取所有Subversion提交:

git svn fetch

完成后,Git将把SVN主干签出到一个新的分支中。任何其他分支都设置为远程。您可以通过以下方式查看其他SVN分支:

git branch -r

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

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

标记作为分支导入。您必须创建一个本地分支,创建一个标记并删除该分支,以便在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

我使用了svn2git脚本,工作起来很有魅力。


Pro Git 8.2对此进行了解释:http://git-scm.com/book/en/Git-and-Other-Systems-Migrating-to-Git


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


从Subversion到Git(或同时使用两者)的平滑迁移有一个新的解决方案:SubGit。

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

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

$ subgit install svn_repos
...
TRANSLATION SUCCESSFUL 

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

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

希望这有帮助!


我只是想把我的贡献加入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 .

TortoiseGit这样做。查看此日志:http://jimmykeen.net/articles/03-nov-2012/how-migrate-from-svn-to-git-windows-using-tortoise-clients

是的,我知道用链接回答不是很好,但这是一个解决方案,嗯?


只使用git、SVN和bash的稍微扩展的答案。它包括SVN存储库的步骤,这些存储库不使用带有主干/分支/标签目录布局的常规布局(SVN绝对不执行这种布局)。

首先使用此bash脚本扫描SVN repo以查找不同的贡献者,并为映射文件生成模板:

#!/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

使用此选项可以创建一个作者文件,在该文件中,您可以使用git-config财产user.name和user.email将svn用户名映射到开发人员设置的用户名和电子邮件(请注意,对于GitHub这样的服务,只有匹配的电子邮件就足够了)。

然后让git-svn将svn存储库克隆到git存储库,告诉它映射:

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

这可能需要非常长的时间,因为git-svn将单独检查存在的每个标记或分支的每个修订。(请注意,SVN中的标记实际上只是分支,因此它们在Git中最终也是如此)。您可以通过删除SVN中不需要的旧标记和分支来加快速度。

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

git-svn-rebase--继续

在很多情况下,你已经在这里完成了。但是,如果您的SVN回购有一个非传统的布局,您只需在SVN中有一个目录,就可以将其放入git分支中,那么您可以执行一些额外的步骤。

最简单的方法是在服务器上创建一个新的SVN repo,它遵循惯例,并使用SVN副本将目录放在主干或分支中。如果您的目录完全位于repo的根目录,这可能是唯一的方法,当我上次尝试这个git-svn时,它只是拒绝执行签出。

您也可以使用git执行此操作。对于git-svn克隆,只需使用您想要放入git分支的目录。

运行后

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

注意,这需要Git1.7或更高版本。


这里有一个简单的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上(秘诀是——关注标签)。

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


atlassian网站上的这份指南是我找到的最好的指南之一:

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

此工具-https://bitbucket.org/atlassian/svn-migration-scripts-对于生成authors.txt等内容也非常有用。


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

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

在SourceTree中打开回购,您将看到您的提交消息也已迁移。

现在转到存储库->存储库设置并添加新的远程存储库详细信息。如果您愿意,请删除SVN远程(我通过“编辑配置文件”选项执行此操作)。

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


您必须安装

git
git-svn

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

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

Subversion只列出每次提交的用户名。Git的提交有更丰富的数据,但最简单的是,提交作者需要列出姓名和电子邮件。默认情况下,git-svn工具只会在author和email字段中列出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:忽略财产到.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存储库

首先,创建一个裸存储库,并使其默认分支与svn的“主干”分支名称匹配。

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将所有Subversion标记都转换为git中的非常短的分支,格式为“tags/name”。您需要使用以下方法将所有这些分支转换为实际的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

这一步需要输入一些信息。:-)但是,不要担心;unixshell将为以git-for-each-ref开头的超长命令提供>辅助提示。


对于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命令产生大量输出,包括顶部的一些警告;我无视警告。


SubGit(vs死亡蓝屏)

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,妈妈。gitsvn让我成为蓝屏死亡。只是不断。git-svn让我厌烦git的“文件名太长”致命错误。

步骤

1.下载SubGit

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

假设我们是为Windows做的(移植到Linux很简单)。在SubGit的安装bin目录(subbit-2.X.X\bin)中,创建两个.bat文件。

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

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

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

您可以在这里添加类似于git-svn的其他参数。我只使用默认域myCompanyDomain.com来修复SVN作者电子邮件地址的域。我有标准的SVN存储库结构(主干/分支/标签),我们在“作者映射”方面没有问题。所以我什么都不做了。

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

技巧1:使用--最小修订版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存储

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

配置遥控器

Run:

$ git remote add origin url://your/repo.git

准备将巨大的本地Git存储库首次发送到远程存储库

默认情况下,Git无法发送大块数据。致命:远端意外挂断

让我们跑吧:

git config --global http.postBuffer 1073741824

524288000-500 MB1073741824-1 GB等。

修复本地证书问题。如果您的git服务器使用了损坏的证书。

我已禁用证书。

此外,您的Git服务器可能存在需要更正的请求量限制。

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

使用本地Git运行:

git push origin --mirror

(git push origin“*:*”用于旧git版本)

如果出现以下错误:error:无法派生git:没有这样的文件或目录。。。对我来说,完全重新创建存储库解决了这个错误(30小时)。您可以尝试以下命令

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

或者尝试重新安装Git(对我来说没用)。或者您可以从所有标签创建分支并推送它们。或者,或者,或者。。。


收回,收回

对于复杂的案件,埃里克·S·雷蒙德(Eric S.Raymond)的收回是首选工具。除了SVN,它还通过快速导出格式和CVS支持许多其他版本控制系统。作者报告了Emacs和FreeBSD等古代存储库的成功转换。

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

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


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

安装svn2git开始菜单->所有程序->Ruby->使用Ruby启动命令提示符然后键入“geminstallsvn2git”并输入迁移子版本存储库打开Ruby命令提示符并转到要迁移文件的目录然后svn2git http://[domainname]/svn/[repository root]将项目迁移到Git可能需要几个小时,具体取决于项目代码大小。这一主要步骤有助于创建如下所述的Git存储库结构。SVN(/Project_components)主干-->Git主机SVN(/Project_components)分支-->Git分支SVN(/Project_components)标记-->Git标记

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


GitHub有一个导入程序。创建存储库后,可以通过其URL从现有存储库导入。如果适用,它将要求您提供证书,然后从那里开始。

当它运行时,它会找到作者,您可以简单地将他们映射到GitHub上的用户。

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


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

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


实现这一目标有不同的方法。我尝试了其中的一些,发现在Windows操作系统上只安装了git和svn就可以了。

前提条件:

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

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

在REPO_NAME_FOLDER目录中创建空存储库(使用控制台工具或tortoiseSVN)cd REPO_NAME_PARENT_FOLDER,将dumpfile.dump放入REPO_NAME_PARENT_FOLDsvnadmin load REPO_NAME_FOLDER<dumpfile.dump等待此操作,可能需要很长时间此命令是无声的,因此打开第二个cmd窗口:svnserve-d-R--root REPO_NAME_FOLDER为什么不直接使用file:///...... ? 因为下一个命令将失败,无法打开。。。到URL:,感谢您的回答https://stackoverflow.com/a/6300968/4953065创建新文件夹SOURCE_GIT_foldercd源_GIT_FOLDERgit-svn克隆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

在我的情况下,我不需要标签命令,因为我的repo没有标签。

祝你好运


我已经发布了一个将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分支创建本地分支

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

如果你想了解更多细节,请阅读我的帖子或询问我。


我们可以使用git-svnclone命令,如下所示。

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

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

svn日志—复制时停止<svn_URL>

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

git svn clone-r<svn_REV_NO>:HEAD--无最小化url--stdlayout--无元数据--作者文件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、branches和标记推送到远程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实用程序删除了带有分支和标记的手动工作。

使用命令sudogeminstallsvn2git安装它。之后运行以下命令。

$svn2git<SVN_URL>--authors.txt--修订版<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-svnclone命令包装器。

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


将svn子模块/文件夹“MyModule”转换为具有历史记录的git,既没有标记也没有分支。

git-svn clone--无元数据--trunk=SomeFolder1/SomeFolder2/SomeFolder3/MyModulehttp://svnhost:port/repo_root_folder/MyModule_temp-一个C: \ccheetah\svn\authors-transform.txtgit克隆MyModule_temp MyModulecd我的模块git流初始化git远程设置url源https://userid@stashhost/stash/scm/xyzxyz/MyModule.gitgit push-u原始主机gitpush-u源代码开发

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


我使用以下脚本读取了一个包含所有SVN存储库列表的文本文件,并将其转换为Git,然后使用gitclone--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的格式为:

(无作者)=罗杰斯王子<prince.rogers.nelson@payesley.park.org>

www数据是Apache web服务器用户,需要权限才能通过HTTP推送更改。


我在一台windows机器上,通过调用

传输.bathttp://svn.my.address/svn/myrepo/trunk https://git.my.address/orga/myrepo

也许任何人都可以使用它。它创建了一个TMP文件夹,用git签出SVN repo,添加新的来源并推送它……然后再次删除文件夹。

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

为此,我使用了svn2git库,过程如下:

sudo apt-get安装git-core git-svn-rubysudo gem安装svn2gitsvn log--quiet|grep-E“r[0-9]+\|.+\|”|cut-d'|'-f2|sed's///g'|sort|uniq>authors.txt(此命令用于映射作者)

以上步骤应该在要从svn转换为git的文件夹中执行。

在authors.txt中每行添加一个映射,如下所示

anand = Anand Tripathi <email_id>
trip = Tripathi Anand <email_id>

为新的git存储库创建一个文件夹,并执行以下命令,路径为authors.txt

svn2git <svn_repo_path> --nobranches --notags --notrunk --no-minimize-url --username <user_name> --verbose  --authors <author.txt_path>

If no trunk and no tag and branch is present then have to execute the above command else if root is trunk then mention rootistrunk or trunk is present then --trunk <trunk_name>

git远程添加原点git push—所有原点git push—标记原点


首先,感谢@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,您可能需要禁用或调整初始推送的设置。


用于SVN到GIT迁移的一体式shell脚本。用占位符提及GIT和SVN详细信息

#!/bin/bash

######## Project name 
PROJECT_NAME="Helloworld"
EMAIL="example mail"

#Credientials Repo
GIT_USER='<git username>'
GIT_PWD='<git password>'
SVN_USER='<svn username>'
SVN_PWD='<svn password>'

######## SVN repository to be migrated # Dont use https - error will be thrown
BASE_SVN="<SVN URL>/Helloworld"

#Organization inside BASE_SVN
BRANCHES="branches"
TAGS="tags"
TRUNK="trunk"

#Credientials
git config --global user.name '<git username>'
git config --global user.password '<git password>'
git config --global credential.helper 'cache --timeout=3600'

######## GIT repository to migrate - Ensure already project created in Git
GIT_URL=https://$GIT_USER:$GIT_PWD@<GIT URL>/Helloworld.git

###########################
#### Don't need to change from here
###########################

#Geral Configuration
ABSOLUTE_PATH=$(pwd)
TMP=$ABSOLUTE_PATH/$PROJECT_NAME

#Branchs Configuration
SVN_BRANCHES=$BASE_SVN/$BRANCHES
SVN_TAGS=$BASE_SVN/$TAGS
SVN_TRUNK=$BASE_SVN/$TRUNK

AUTHORS=$PROJECT_NAME"-authors.txt"

echo '[LOG] Starting migration of '$SVN_TRUNK
echo '[LOG] Using: '$(git --version)
echo '[LOG] Using: '$(svn --version | grep svn,)

mkdir $TMP
echo
echo '[DIR] cd' $TMP
cd $TMP

echo
echo '[LOG] Getting authors'
svn --username $SVN_USER --password $SVN_PWD log -q $BASE_SVN | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2"@"$EMAIL">"}' | sort -u >> $AUTHORS

echo
echo '[RUN] git svn clone --authors-file='$AUTHORS' --trunk='$TRUNK' --branches='$BRANCHES' --tags='$TAGS $BASE_SVN $TMP
git svn clone --authors-file=$AUTHORS --trunk=$TRUNK --branches=$BRANCHES --tags=$TAGS $BASE_SVN $TMP

#Not working so no need to mention it
#--stdlayout $PROJECT_NAME
echo
echo '[RUN] svn ls '$SVN_BRANCHES
svn ls $SVN_BRANCHES

echo 
echo 'git branch -a'
git branch -a

echo
echo '[LOG] Getting first revision'
FIRST_REVISION=$( svn log -r 1:HEAD --limit 1 $BASE_SVN | awk -F '|' '/^r/ {sub("^ ", "", $1); sub(" $", "", $1); print $1}' )

echo
echo '[RUN] git svn fetch -'$FIRST_REVISION':HEAD'
git svn fetch -$FIRST_REVISION:HEAD

#Branches and Tags  
echo
echo '[RUN] svn ls '$SVN_BRANCHES
for BRANCH in $(svn ls $SVN_BRANCHES); do
    echo git branch ${BRANCH%/} remotes/svn/${BRANCH%/}
    git branch ${BRANCH%/} remotes/svn/${BRANCH%/}
done

git for-each-ref --format="%(refname:short) %(objectname)" refs/remotes/origin/tags | grep -v "@" | cut -d / -f 3- |
while read ref
do
  echo git tag -a $ref -m 'import tag from svn'
  git tag -a $ref -m 'import tag from svn'
done

git for-each-ref --format="%(refname:short)" refs/remotes/origin/tags | cut -d / -f 1- |
while read ref
do
  git branch -rd $ref
done
  
echo
echo 'git tag'
git tag

echo
echo 'git show-ref --tags'
git show-ref --tags

echo
echo '[RUN] git remote add origin '$GIT_URL
git remote add origin $GIT_URL

echo
echo '[RUN] git push'
git push origin --all --force
git push origin --tags

#echo git branch -d -r trunk
#git branch -d -r trunk

git config --global credential.helper cache
echo 'Successful.'

当您运行上述脚本时,它将从SVN中获取分支和标记详细信息,并将其放在.git文件夹下。交叉检查SVN中是否存在所有分支,这些分支应在此.git/refs/heads文件夹下可用。如果SVN中缺少一些分支,请手动将分支文件从.git/refs/remotes/origin/<branches>复制到.git/refs/heads只复制分支(包括主分支),如果有标记或主干,则忽略。现在再次运行脚本。您可以在git存储库中看到所有分支和标记。