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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/79165/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 05:46:54  来源:igfitidea点击:

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

svngitversion-controlgit-svn

提问by Milan Babu?kov

I read the Git manual, FAQ, Git - SVN crash course, etc. and they all explain this and that, but nowhere can you find a simple instruction like:

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

SVN repository in: svn://myserver/path/to/svn/repos

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

Git repository in: git://myserver/path/to/git/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

I don't expect it to be that simple, and I don't expect it to be a single command. But I do expect it not to try to explain anything - just to say what steps to take given this example.

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

采纳答案by jfm3

Magic:

魔法:

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

Git and SVN operate very differently. You need to learn Git, and if you want to track changes from SVN upstream, you need to learn git-svn. The git-svnmain page has a good examples section:

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

$ git svn --help

回答by cmcginty

Create a users file (i.e. users.txt) for mapping SVN users to Git:

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

user1 = First Last Name <[email protected]>
user2 = First Last Name <[email protected]>
...

You can use this one-liner to build a template from your existing SVN repository:

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

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

SVN will stop if it finds a missing SVN user not in the file. But after that you can update the file and pick-up where you left off.

如果发现文件中没有丢失的 SVN 用户,SVN 将停止。但在那之后,您可以更新文件并从上次中断的地方继续。

Now pull the SVN data from the repository:

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

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

This command will create a new Git repository in dest_dir-tmpand start pulling the SVN repository. Note that the "--stdlayout" flag implies you have the common "trunk/, branches/, tags/" SVN layout. If your layout differs, become familiar with --tags, --branches, --trunkoptions (in general git svn help).

此命令将在其中创建一个新的 Git 存储库dest_dir-tmp并开始拉取 SVN 存储库。请注意,“--stdlayout”标志意味着您具有常见的“主干/,分支/,标签/”SVN 布局。如果您的布局不同,请熟悉--tags, --branches,--trunk选项(通常为git svn help)。

All common protocols are allowed: svn://, http://, https://. The URL should target the base repository, something like http://svn.mycompany.com/myrepo/repository. The URL string must notinclude /trunk, /tagor /branches.

允许使用所有常用协议:svn://http://https://。URL 应该针对基本存储库,类似于http://svn.mycompany.com/myrepo/repository。URL 字符串不得包含/trunk,/tag/branches

Note that after executing this command it very often looks like the operation is "hanging/freezed", and it's quite normal that it can be stuck for a long time after initializing the new repository. Eventually you will then see log messages which indicates that it's migrating.

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

Also note that if you omit the --no-metadataflag, Git will append information about the corresponding SVN revision to the commit message (i.e. git-svn-id: svn://svn.mycompany.com/myrepo/<branchname/trunk>@<RevisionNumber> <Repository UUID>)

另请注意,如果省略该--no-metadata标志,Git 将在提交消息中附加有关相应 SVN 修订版的信息(即git-svn-id: svn://svn.mycompany.com/myrepo/<branchname/trunk>@<RevisionNumber> <Repository UUID>

If a user name is not found, update your users.txtfile then:

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

cd dest_dir-tmp
git svn fetch

You might have to repeat that last command several times, if you have a large project, until all of the Subversion commits have been fetched:

如果你有一个大项目,你可能需要多次重复最后一个命令,直到所有的 Subversion 提交都被获取:

git svn fetch

When completed, Git will checkout the SVN trunkinto a new branch. Any other branches are setup as remotes. You can view the other SVN branches with:

完成后,Git 会将 SVN 检出trunk到一个新分支。任何其他分支都设置为遥控器。您可以使用以下命令查看其他 SVN 分支:

git branch -r

If you want to keep other remote branches in your repository, you want to create a local branch for each one manually. (Skip trunk/master.) If you don't do this, the branches won't get cloned in the final step.

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

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

Tags are imported as branches. You have to create a local branch, make a tag and delete the branch to have them as tags in Git. To do it with tag "v1":

标签作为分支导入。您必须创建一个本地分支,创建一个标签并删除该分支以将它们作为 Git 中的标签。用标签“v1”来做到这一点:

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

Clone your GIT-SVN repository into a clean Git repository:

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

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

The local branches that you created earlier from remote branches will only have been copied as remote branches into the new cloned repository. (Skip trunk/master.) For each branch you want to keep:

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

git checkout -b local_branch origin/remote_branch

Finally, remove the remote from your clean Git repository that points to the now deleted temporary repository:

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

git remote rm origin

回答by Eugene Yokota

Cleanly Migrate Your Subversion Repository To a Git Repository. First you have to create a file that maps your Subversion commit author names to Git commiters, say ~/authors.txt:

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

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

Then you can download the Subversion data into a Git repository:

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

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

If you're on a Mac, you can get git-svnfrom MacPorts by installing git-core +svn.

如果您使用的是 Mac,则可以git-svn通过安装git-core +svn.

If your subversion repository is on the same machine as your desired git repository, then you can use this syntax for the init step, otherwise all the same:

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

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

回答by Thiago Le?o Moreira

I used the svn2git scriptand works like a charm.

我使用了svn2git 脚本,效果很好

回答by webmat

I suggest getting comfortable with Git before trying to use git-svn constantly, i.e. keeping SVN as the centralized repo and using Git locally.

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

However, for a simple migration with all the history, here are the few simple steps:

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

Initialize the local repo:

初始化本地仓库:

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

Mark how far back you want to start importing revisions:

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

git svn fetch -r42

(or just "git svn fetch" for all revs)

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

Actually fetch everything since then:

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

git svn rebase

You can check the result of the import with Gitk. I'm not sure if this works on Windows, it works on OSX and Linux:

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

gitk

When you've got your SVN repo cloned locally, you may want to push it to a centralized Git repo for easier collaboration.

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

First create your empty remote repo (maybe on GitHub?):

首先创建你的空远程仓库(可能在GitHub 上?):

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

Then, optionally sync your main branch so the pull operation will automatically merge the remote master with your local master, when both contain new stuff:

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

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

After that, you may be interested in trying out my very own git_remote_branchtool, which helps dealing with remote branches:

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

First explanatory post: "Git remote branches"

第一篇解说:《Git远程分支

Follow-up for the most recent version: "Time to git collaborating with git_remote_branch"

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

回答by Alexander Kitaev

There is a new solution for smooth migration from Subversion to Git (or for using both simultaneously): SubGit.

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

I'm working on this project myself. We use SubGit in our repositories - some of my teammates use Git and some Subversion and so far it works very well.

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

To migrate from Subversion to Git with SubGit you need to run:

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

$ subgit install svn_repos
...
TRANSLATION SUCCESSFUL 

After that you'll get Git repository in svn_repos/.git and may clone it, or just continue to use Subversion and this new Git repository together: SubGit will make sure that both are always kept in sync.

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

In case your Subversion repository contains multiple projects, then multiple Git repositories will be created in svn_repos/git directory. To customize translation before running it do the following:

如果您的 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

With SubGityou may migrate to pure Git (not git-svn) and start using it while still keeping Subversion as long as you need it (for your already configured build tools, for instance).

使用SubGit,你可以迁移到纯 Git(不是 git-svn)并开始使用它,同时只要你需要它仍然保留 Subversion(例如,对于你已经配置的构建工具)。

Hope this helps!

希望这可以帮助!

回答by EfForEffort

See the official git-svn manpage. In particular, look under "Basic Examples":

请参阅官方git-svn 联机帮助页。特别是,在“基本示例”下查看:

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

跟踪和贡献整个 Subversion 管理的项目(包括主干、标签和分支):

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

回答by it3xl

SubGit(vs Blue Screen of Death)

SubGit(与蓝屏死机)

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

It's all.

这就是全部。

+ To update from SVN, a Git repository created by the first command.

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

subgit import  directory/path/Local.git.Repo


I used a way to migrate to Git instantly for a huge repository.
Of course you need some preparation.
But you may don't stop development process, at all.

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

Here is my way.

这是我的方式。

My solution looks like:

我的解决方案如下:

  • Migrate SVN to a Git repository
  • Update the Git repository just before team's switching to.
  • 将 SVN 迁移到 Git 存储库
  • 在团队切换到 .git 之前更新 Git 存储库

Migration takes a lot of time for a big SVN repository.
But updating of the completed migration just seconds.

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

Of course I'm using SubGit, mama. git-svn makes me Blue Screen of Death. Just constantly. And git-svn is boring me with Git's "filename too long" fatal error.

当然,我正在使用SubGit,妈妈。git-svn 让我蓝屏死机。只是不断。并且 git-svn 对 Git 的“文件名太长”致命错误感到厌烦。

STEPS

脚步

1.Download SubGit

1.下载子Git

2.Prepare migrate and updating commands.

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

Let's say we do it for Windows (it's trivial to port to Linux).
In a SubGit's installation bindirectory (subgit-2.X.X\bin), create two .bat files.

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

Content of a file/command for the migration:

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

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

The "start" command is optional here (Windows). It'll allow to see errors on start and left a shell opened after completion of the SubGit.

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

You may add here additional parameters similar to git-svn. I'm using only --default-domain myCompanyDomain.comto fix the domain of the email address of SVN authors.
I have the standard SVN repository's structure (trunk/branches/tags) and we didn't have troubles with "authors mapping". So I'm doing nothing any more.

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

(If you want to migrate tags like branches or your SVN have multiple branches/tags folders you may consider to use the more verbose SubGit approach)

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

Tip 1: Use --minimal-revision YourSvnRevNumber to see fast how things boils out (some kind of a debugging). Especially useful is to see resolved author names or emails.
Or to limit the migration history depth.

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

Tip 2: Migration may be interrupted (Ctrl+ C) and restored by running of the next updating command/file.
I don't advise doing this for big repositories. I have received "Out of memory Java+Windows exception".

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

Tip 3: Better to create a copy of your result bare repository.

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

Content of a file/command for updating:

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

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

You may run it any amount of times when you want to obtain the last team's commits to your Git repository.

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

Warning!Don't touch your bare repository (creation of branches for example).
You'll take the next fatal error:

警告!不要接触你的裸仓库(例如创建分支)。
你会犯下一个致命错误:

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

不可恢复的错误:不同步且无法同步...正在将 Subversion 修订版转换为 Git 提交...

3.Run the first command/file. It'll take a loooong time for a big repository. 30 hours for my humble repository.

3.运行第一个命令/文件。大型存储库需要很长时间。我简陋的存储库需要 30 个小时。

It's all.
You may update your Git repository from SVN at any time any amount of times by running the second file/command. And before switching of your development team to Git.
It'll take just seconds.

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





There's one more useful task.

还有一项更有用的任务。

Push your local Git repository to a remote Git repository

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

Is it your case? Let's proceed.

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

  1. Configure your remotes
  1. 配置你的遥控器

Run:

跑:

$ git remote add origin url://your/repo.git
  1. Prepare to initial send of your huge local Git repository to a remote repository
  1. 准备将庞大的本地 Git 存储库初始发送到远程存储库

By default your Git can't send big chunks. fatal: The remote end hung up unexpectedly

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

Let's run for it:

让我们为它奔跑吧:

git config --global http.postBuffer 1073741824

524288000 - 500 MB 1073741824 - 1 GB, etc.

524288000 - 500 MB 1073741824 - 1 GB 等。

Fix your local certificate troubles. If your git-server uses a broken certificate.

修复您的本地证书问题。如果您的 git-server 使用损坏的证书。

I have disabled certificates.

我已禁用证书

Also your Git server may have a request amount limitations needing to be corrected.

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

  1. Push all migrationto the team's remote Git repository.
  1. 将所有迁移推送到团队的远程 Git 存储库。

Run with a local Git:

使用本地 Git 运行:

git push origin --mirror

(git push origin '*:*'for old Git versions)

git push origin '*:*'对于旧的 Git 版本)

If you get the following: error: cannot spawn git: No such file or directory... For me the full recreation of my repository solves this error (30 hours). You can try the next commands

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

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

Or try to reinstall Git(useless for me). Or you may create branches from all you tags and push them. Or, or, or...

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

回答by krlmlr

reposurgeon

再生外科医生

For complicated cases, reposurgeon by Eric S. Raymondis the tool of choice. In addition to SVN, it supports many other version control systems via the fast-exportformat, and also CVS. The author reports successful conversions of ancient repositories such as Emacsand FreeBSD.

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

The tool apparently aims at near perfect conversion(such as converting SVN's svn:ignoreproperties to .gitignorefiles) even for difficult repository layouts with a long history. For many cases, other tools might be easier to use.

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

Before delving into the documentation of the reposurgeoncommand line, be sure to read the excellent DVCS migration guidewhich goes over the conversion process step by step.

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