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

How do I migrate an SVN repository with history to a new Git repository?

我阅读了git手册、常见问题解答、git-svn速成课程等,它们都解释了这一点,但是没有一个简单的说明,比如:

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

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

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

我不希望它如此简单,也不希望它只是一个命令。但我希望它不会试图解释任何事情——只是在给出这个例子的情况下说应该采取什么步骤。


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

1
2
3
user1 = First Last Name
user2 = First Last Name
...

您可以使用此一行程序从现有的SVN存储库构建模板:

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

如果SVN发现文件中没有丢失的SVN用户,它将停止。但在那之后,你可以更新文件并从你离开的地方取东西。

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

1
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 help)。

所有常用协议都允许:svn://http://https://。URL应该以基本存储库为目标,比如http://svn.mycompany.com/myrepo/repository。不包括/trunk/tag/branches

请注意,执行此命令后,操作通常看起来像是"挂起/冻结",并且在初始化新的存储库之后,它可能会停留很长时间,这是很正常的。最后,您将看到日志消息,表明它正在迁移。

还要注意,如果省略了--no-metadata标志,那么git将在提交消息(即git-svn-id: svn://svn.mycompany.com/myrepo/@ 中)中附加有关相应SVN修订的信息。

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

1
2
cd dest_dir-tmp
git svn fetch

如果您有一个大型项目,那么您可能需要重复上一个命令几次,直到获取了所有的Subversion提交:

1
git svn fetch

完成后,Git将把svn trunk签入新的分支机构。任何其他分支都设置为远程。您可以使用以下方式查看其他SVN分支:

1
git branch -r

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

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

标记作为分支导入。您必须创建一个本地分支,制作一个标记,然后删除该分支,使它们在Git中成为标记。要使用标签"v1"执行此操作:

1
2
3
4
git checkout -b tag_v1 remotes/tags/v1
git checkout master
git tag v1 tag_v1
git branch -D tag_v1

将您的Git-SVN存储库克隆到干净的Git存储库中:

1
2
3
git clone dest_dir-tmp dest_dir
rm -rf dest_dir-tmp
cd dest_dir

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

1
git checkout -b local_branch origin/remote_branch

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

1
git remote rm origin


马吉克:

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

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

1
$ git svn --help


将您的Subversion存储库干净地迁移到Git存储库。首先,您必须创建一个文件,将您的subversion commit作者名称映射到git committers,例如~/authors.txt

1
2
jmaddox = Jon Maddox <[email protected]>
bigpappa = Brian Biggs <[email protected]>

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

1
2
3
4
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步骤使用此语法,否则将完全相同:

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


我用的是svn2git脚本,工作起来很有魅力。


我建议在不断尝试使用Git SVN之前先熟悉Git,即将SVN作为集中回购,并在本地使用Git。

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

初始化本地回购:

1
2
3
mkdir project
cd project
git svn init http://svn.url

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

1
git svn fetch -r42

(或只是所有版本的"git svn fetch")。

实际上,从那时起获取所有内容:

1
git svn rebase

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

1
gitk

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

首先创建空的远程回购(可能在GitHub上?):

1
git remote add origin [email protected]:user/project-name.git

然后,可以选择同步您的主分支,这样拉操作将自动合并远程主控形状和本地主控形状,当两者都包含新内容时:

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

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

第一篇解释性文章:"Git远程分支"

最新版本的后续行动:"时间到Git与Git_远程_分支协作"


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

我自己在做这个项目。我们在存储库中使用了subgit——我的一些队友使用了git和一些subversion,到目前为止它工作得非常好。

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

1
2
3
$ subgit install svn_repos
...
TRANSLATION SUCCESSFUL

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

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

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

使用subgit,您可以迁移到pure-git(而不是git-svn)并开始使用它,同时还可以根据需要保留子版本(例如,对于已经配置的构建工具)。

希望这有帮助!


请参见Git Svn官方手册页。特别是在"基本示例"下:

Tracking and contributing to an entire Subversion-managed project (complete
with a trunk, tags and branches):

1
2
# 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(与死亡蓝屏对比)

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

就这样。好的。

+要从svn进行更新,它是由第一个命令创建的Git存储库。好的。

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

我使用了一种方法来立即迁移到Git,以获得一个巨大的存储库。< BR>当然你需要一些准备。< BR>但您可能根本不会停止开发过程。好的。

这是我的路。好的。

我的解决方案如下:好的。

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

迁移对于一个大型的SVN存储库来说需要很多时间。< BR>但更新完成的迁移只需几秒钟。好的。

当然我用的是Subgit,妈妈。Gitsvn让我看到死亡的蓝屏。只是不断地。GitSvn用Git的"文件名太长"致命错误让我厌烦。好的。

步骤好的。

1。下载子目录好的。

2。准备迁移和更新命令。好的。

假设我们是为Windows做的(移植到Linux很简单)。< BR>在subgit的安装bin目录(subgit-2.x.xin)中,创建两个.bat文件。好的。

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

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

"start"命令在这里是可选的(windows)。它将允许在开始时查看错误,并在完成子Git后打开一个shell。好的。

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

(如果要迁移标记,如分支或SVN具有多个分支/标记文件夹,可以考虑使用更详细的子Git方法)好的。

提示1:使用--minimal revision yoursvnrevnumber快速查看事情的发展(某种调试)。特别有用的是查看解析的作者姓名或电子邮件。< BR>或者限制迁移历史深度。好的。

提示2:迁移可能被中断(ctrl+c),并通过运行下一个更新命令/文件来恢复。< BR>我不建议在大型存储库中这样做。我收到了"内存不足的Java + Windows异常"。好的。

提示3:最好创建结果裸机存储库的副本。好的。

要更新的文件/命令的内容:好的。

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

当您想要获得最后一个团队对您的Git存储库的提交时,您可以运行它任意次数。好的。

警告!不要触摸您的裸存储库(例如创建分支)。< BR>下一个致命错误是:好的。

Unrecoverable error: are out of sync and cannot be synced ... Translating Subversion revisions to Git commits...

Ok.

三。运行第一个命令/文件。对于一个大的仓库来说,这需要很长的时间。30小时为我简陋的仓库。好的。

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

还有一个更有用的任务。好的。

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

是你的案子吗?让我们继续。好的。

  • 配置遥控器
  • 运行:好的。

    1
    $ git remote add origin url://your/repo.git
  • 准备将大型本地Git存储库初始发送到远程存储库
  • 默认情况下,您的Git不能发送大数据块。致命:远程端意外挂断好的。

    让我们跑过去:好的。

    1
    git config --global http.postBuffer 1073741824

    524288000-500 MB1073741824-1 GB等。好的。

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

    我有禁用的证书。好的。

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

  • 将所有迁移推送到团队的远程Git存储库。
  • 使用本地Git运行:好的。

    1
    git push origin --mirror

    (对于旧的git版本,git push源代码"*:*")好的。

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

    1
    2
    git push origin --all
    git push origin --tags

    或者尝试重新安装Git(对我来说没用)。或者您可以从所有标记中创建分支并将其推送。或,或,或…好的。好啊。


    知识库

    对于复杂的病例,Eric S.Raymond的再手术是首选的工具。除了SVN之外,它还通过fast-export格式和cvs支持许多其他版本控制系统。作者报告了诸如emacs和freebsd等古代存储库的成功转换。

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

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


    Atlassian网站上的本指南是我发现的最好的指南之一:

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

    这个工具-https://bitback.org/atlassian/svn-migration-scripts-对于生成authors.txt和其他东西也非常有用。


    你必须安装

    1
    2
    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签出的根目录中,运行以下命令:

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

    这将抓取所有日志消息,提取用户名,消除任何重复的用户名,对用户名进行排序,并将它们放入"authors transform.txt"文件中。现在编辑文件中的每一行。例如,转换:

    1
    jwilkins = jwilkins <jwilkins>

    进入这个:

    1
    jwilkins = John Albin Wilkins <[email protected]>

    2。使用git svn克隆Subversion存储库

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

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

    三。转换svn:忽略属性到.gitignore

    如果您的SVN repo使用的是svn:ignore属性,则可以使用以下方法轻松地将其转换为.gitignore文件:

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

    4。将存储库推送到裸Git存储库

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

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

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

    1
    2
    3
    4
    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的标准"主"分支:

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

    6。清理树枝和标签

    GitSvn以"tags/name"的形式将所有Subversion标记制作成Git中非常短的分支。您将希望使用以下方法将所有这些分支转换为实际的git标记:

    1
    2
    3
    4
    5
    6
    7
    8
    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存储库导入的功能。不过,我从未尝试过。


    只使用git、svn和bash的扩展回答。它包括SVN存储库的步骤,这些步骤不使用传统布局和主干/分支/标签目录布局(SVN完全不执行这种布局)。

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

    1
    2
    3
    4
    5
    #!/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.nameuser.email的开发人员设置的用户名和电子邮件(注意,对于像github这样的服务,只有匹配的电子邮件就足够了)。

    然后让git svn将SVN存储库克隆到一个git存储库,告诉它有关映射的信息:

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

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

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

    git svn rebase --continue

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

    最简单的方法是在服务器上创建一个新的SVN repo,它遵循约定,并使用svn copy将目录放在主干或分支中。这可能是唯一的方法,如果您的目录一直在回购的根目录,当我上次尝试这个git svn只是拒绝做结帐。

    你也可以用git来实现。对于git svn clone,只需使用要放在git分支中的目录即可。

    运行后

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

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


    我已经发布了一个逐步的指南(这里)来将svn转换成git,包括将svn标签转换成git标签,将svn分支转换成git分支。

    短版:

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

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

    2)获取SVN数据。这一步是最需要时间的一步。

    1
    2
    cd gitreponame
    git svn fetch

    重复git svn fetch,直到无错误完成

    3)更新主分支

    1
    git svn rebase

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

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

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

    1
    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

    1
    2
    3
    git remotes add newrepo [email protected]:aUser/aProjectName.git
    git push newrepo refs/heads/*
    git push --tags newrepo

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


    乌龟是这样做的。请参阅以下博客文章:http://jimmykeen.net/articles/03-nov-2012/how-migrate-from-svn-to-git-windows-using-tortoise-clients

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


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

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

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

    • svn log --stop-on-copy

    上面的命令将在创建SVN项目时提供第一个版本号。

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

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

    问题是它不会将分支和标记转换为push。你必须手动操作。例如下面的分支:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    $ 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
    $

    标签:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    $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、分支和标记推送到远程git存储库。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ 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 --authors authors.txt --revision

    现在您可以列出分支、标签并轻松地推送它们。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ 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命令的一个很好的包装。

    有关完整的示例,请参阅我的日志。


    对于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 [email protected]进行测试)。
      • 项目favourite-project是在dev-team名称空间中创建的。
    • 文件users.txt包含相关的用户详细信息,每行一个用户,格式为username = First Last ,其中username是SVN日志中给出的用户名。(有关详细信息,请参阅参考资料部分的第一个链接,尤其是用户凯西的回答)。

    版本

    • Subversion版本1.6.17(R1128011)
    • Git版本1.9.1
    • Gitlab版本7.2.1 ff1633f
    • Ubuntu服务器14.04

    命令

    1
    2
    3
    4
    5
    6
    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 [email protected]:dev-team/favourite-project.git
    git push --set-upstream gitlab master

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

    笔记

    • 如果有未知用户,git svn clone命令将停止,在这种情况下,更新users.txtcd favourite-projectgit svn fetch将从停止的地方继续。
    • SVN存储库需要标准的trunk-tags-branches布局。
    • git svn clone命令的svn url停在trunk/tags/branches/的正上方。
    • git svn clone命令产生大量输出,包括顶部的一些警告;我忽略了这些警告。


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


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

  • 输入远程SVN URL作为"源路径/URL"。
  • 提示时输入您的凭据。
  • 输入本地文件夹位置作为"目标路径"。
  • 给它起个名字。
  • 在高级选项中,从"创建本地"下拉列表中选择"Git"。类型为""的存储库。
  • 您可以选择指定要从中克隆的修订。
  • 击中克隆。
  • 打开sourcetree中的repo,您将看到提交消息也已迁移。

    现在转到repository->repository settings并添加新的远程repo详细信息。如果您愿意,请删除SVN远程(我是通过"编辑配置文件"选项完成的)。

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


    我在一台Windows机器上,做了一个小批量,只需调用

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

    也许任何人都可以用它。它创建了一个tmp文件夹,用git检查那里的svn repo,并添加新的源文件并将其推送…再次删除文件夹。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    @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%

    您仍然需要用户映射为

    1
    User1 = User One <[email protected]>


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

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

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

    我费了很大的劲才把十几个SVN存储库从谷歌代码转移到了Github。我用窗户也没用。Ruby在我的旧Debian盒子上坏了各种各样,让它在Windows上工作是个笑话。其他解决方案无法使用cygwin路径。即使我得到了一些有用的东西,我也不知道如何让标签出现在Github上(秘密是——跟踪标签)。

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


    另一方面,当使用git svn dcommits尝试git时,git stash命令是上帝的恩赐。

    一个典型的过程:

  • 设立GIT回购协议
  • 对不同的文件做一些工作
  • 决定签入一些工作,使用git
  • 决定向svn-dcommit提交
  • 获取可怕的"不能用脏索引提交"错误。
  • 解决方案(需要Git 1.5.3+):

    1
    git stash; git svn dcommit ; git stash apply

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

    https://github.com/onepremise/sgms网站

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    /trunk
      /Project1
      /Project2
    /branches
         /Project1
         /Project2
    /tags
     /Project1
     /Project2

    该方案也很受欢迎和支持:

    1
    2
    3
    4
    5
    6
    7
    8
    /Project1
         /trunk
         /branches
         /tags
    /Project2
         /trunk
         /branches
         /tags

    每个项目将按项目名称同步:

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

    如果要转换完整回购,请使用以下语法:

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


    我使用以下脚本读取一个文本文件,该文件包含我的所有SVN存储库的列表,并将它们转换为Git,然后使用git clone --bare转换为纯Git存储库:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #!/bin/bash
    file="list.txt"
    while IFS= read -r repo_name
    do
     printf '%s
    '"$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的格式为:

    1
    2
    repo1_name
    repo2_name

    users.txt的格式如下:

    (no author) = Prince Rogers

    WWW数据是ApacheWeb服务器用户,通过HTTP推送更改需要权限。


    将SVN子模块/文件夹"mymodule"转换为具有历史记录且不带标记或分支的Git。

    • Git SVN克隆--无元数据--trunk=somefolder1/somefolder2/somefolder3/mymodule http://svnhost:port/repo_root_folder/mymodule_temp-aC:Cheetahsvnauthors-transform.txt文件
    • git克隆mymodule_temp mymodule
    • 光盘模块
    • Git流初始化
    • Git远程设置URL源https://userid@stashhost/stash/scm/xyzxyz/mymodule.git
    • git push-u原始主机
    • Git Push-U起源开发

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


    在Subversion中有效地使用Git是对Git SVN的一个温和介绍。对于现有的SVN存储库,Git SVN使这变得非常容易。如果您正在启动一个新的存储库,那么首先创建一个空的SVN存储库,然后使用Git SVN导入要比向相反的方向导入要容易得多。可以创建一个新的Git存储库,然后导入到SVN中,但这有点痛苦,特别是如果您刚接触Git并希望保留提交历史记录的话。


    这里有几个答案可以参考https://github.com/nirvdrum/svn2git,但是对于大型存储库,这可能会很慢。我尝试过使用https://github.com/svn-all-fast-export/svn2git,这是一个名称完全相同但用于将kde从svn迁移到git的工具。

    设置它的工作稍微多一点,但当完成转换后,我自己花了几分钟时间完成了另一个脚本花费数小时的转换。


    Github有一个进口商。创建存储库后,可以通过其URL从现有存储库导入。如果适用的话,它会要求您提供凭证,然后从那里开始。

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

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


    下载Ruby Installer for Windows并安装最新版本。将Ruby可执行文件添加到您的路径中。

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

      迁移Subversion存储库

    • 打开ruby命令提示符并转到要迁移文件的目录

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

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

    • 这个主要步骤有助于创建下面提到的Git存储库结构。

      SVN(/project_components)trunk-->git masterSVN(/project_components)分支-->git分支svn(/project_components)标记-->git标记

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


    实现这一目标有不同的方法。我已经尝试了其中的一些方法,发现真正有效的方法是在Windows操作系统上安装Git和SVN。

    先决条件:

  • Windows上的Git(我用过这个)https://git-scm.com/
  • 安装了控制台工具的SVN(我使用了Tortoise SVN)
  • 转储SVN存储库的文件。svnadmin dump /path/to/repository > repo_name.svn_dump
  • 实现最终目标的步骤(将所有具有历史记录的存储库移动到Git,首先是本地Git,然后是远程存储库)

  • 在目录repo_name_文件夹中创建空存储库(使用控制台工具或Tortoissesvn)cd REPO_NAME_PARENT_FOLDER将dumpfile.dump放入repo-name_父文件夹

  • svnadmin load REPO_NAME_FOLDER < dumpfile.dump等这个操作,可能要长时间

  • 这个命令是无声的,所以打开第二个命令窗口:svnserve -d -R --root REPO_NAME_FOLDER。为什么不直接使用文件:///……?由于回答https://stackoverflow.com/a/6300968/4953065,下一个命令将在Unable to open ... to URL:中失败。

  • 创建新文件夹源Git文件夹

  • cd SOURCE_GIT_FOLDER
  • git svn clone svn://localhost/wait等待此操作。
  • 最后,我们得到了什么?

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

    1
    git log

    看到你以前的承诺了吗?如果是-好

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

    1
    2
    3
    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

    在我的例子中,我不需要tags命令,因为我的repo没有tags。

    祝你好运!


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

    sudo apt-get install git-core git-svn ruby
    sudo gem install svn2git
    svn log --quiet | grep -E"r[0-9]+ \| .+ \|" | cut -d'|' -f2 | sed 's/ //g' | sort | uniq > authors.txt (this command is for mapping the authors)

    上面的步骤应该在将要从SVN转换为Git的文件夹中执行。

    Add one mapping per line in authors.txt like this

    1
    2
    anand = Anand Tripathi
    trip = Tripathi Anand

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

    1
    2
    3
    svn2git <svn_repo_path> --nobranches --notags --notrunk --no-minimize-url --username <user_name> --verbose  --authors

    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 remote add origin
    git push --all origin
    git push --tags origin